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é?

15
demandé sur ネロク 2011-08-30 18:57:59

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.

17
répondu Luc Danton 2011-08-30 15:18:59

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.

8
répondu Bo Persson 2011-08-30 15:13:20

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)

8
répondu David Rodríguez - dribeas 2017-09-25 12:03:12

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.

3
répondu AProgrammer 2011-08-30 15:12:31