Syntaxe des modèles C++ avec les paramètres de type de fonction
j'ai l'habitude de voir une syntaxe comme celle-ci pour les pointeurs de fonction
int (*pointer_name) (float, char *);
void call_function (void (*)(int), int);
En C++03 fonctionnelle bibliothèques je vois des types utilisés de cette manière:
abc::function<void(*)(int,float)> f;
En C++11 std::function
je vois le type de donnée de cette façon
std::function<void(int,float)> f;
Il manque une (*)
. Pourquoi?
Le C++03 function<T>
a T
étant un type identique au pointeur de fonction correspondant. Il est facile d'imaginer la mise en œuvre.
std::function
EN C++11 est supporté par langage de base des améliorations. Les types d'arguments de modèle ont-ils été étendus pour accommoder la callabilité?
4 réponses
boost::function) ne stocke pas seulement les pointeurs de fonction. Il peut également stocker des objets de fonction. En ce sens, le passage d'un fonction signature comme paramètre de template est similaire à la façon dont un pointeur intelligent prend habituellement le type de pointee comme paramètre de template, pas un type de pointeur!
Contraste:
int* p; // indirection to an object of type int
std::unique_ptr<int> q; // indirection to an object of type int
typedef void signature_type(); // a function type
// indirection to something callable with signature_type as a signature
// i.e. f() has type void
// only work for freestanding functions however
signature_type* f;
// indirection to something callable with signature_type as a signature
// i.e. g() has type void
// not restricted to function pointers!
std::function<signature_type> g;
il s'agit d'une convention utile.
Il n'y a rien de magique ici, le type
void(int,float)
est le type d'une fonction sans nom. Elle correspond à une fonction comme void g(int x, float y)
.
avec les gabarits vous ne faites pas utiliser des pointeurs de fonction, vous pouvez utiliser des types de fonction.
Comme avec d'autres éléments, les fonctions ont un type, et vous pouvez utiliser soit le type ou le pointeur vers le type dans des contextes différents. Manquant (*)
vous vous attendez est juste l' pointeur syntaxe.
int (*pointer_name) (float, char *);
typedef int my_function_type(float,char*);
my_function_type * pointer_name2;
les types de pointer_name
et pointer_name2
sont les mêmes: pointeur vers une fonction qui retourne int
et prend deux arguments de types float
et char*
. Notez que c'est exactement équivalent à d'autres types comme int
, avec le différence que vous ne pouvez pas déclarer une variable de type function, seulement pointeur vers la fonction.
L'interface de std::function
(ou boost::function
) prend juste le signature de la fonction. Le type d'argument n'est pas un pointeur vers la fonction mais plutôt le type d'une fonction (comme my_function_type
dans le code ci-dessus)
les types de fonctions ne sont pas nouveaux en C++11 (Voir 8.3.5 en C++98). IIRC, l'amélioration en plus de ce TR1 et de stimuler fournir pour function
sont tout à fait mineures.