Pourquoi les fonctions membres ne peuvent pas être utilisées comme arguments de modèle?

Pourquoi les fonctions membres ne peuvent pas être utilisées comme arguments de modèle? Par exemple, je veux faire comme:

struct Foo { void Bar() { // do something } }; template  void Call(TOwner *p) { p->func(); } int main() { Foo a; Call(&a); return 0; } 

Je sais qu’une chose similaire peut être faite en utilisant des pointeurs vers les membres; eh bien, c’est assez cool la plupart du temps, mais je suis juste curieux de savoir pourquoi les pointeurs “devraient” être utilisés.

Je ne vois aucune ambiguïté dans l’interprétation de “p-> func ()” ci-dessus. Pourquoi la norme nous interdit d’utiliser les fonctions membres comme arguments de modèle? Même les fonctions membres statiques ne sont pas autorisées selon mon compilateur (VC ++ 2013). Est-ce que quelqu’un connaît la raison? Ou, existe-t-il un moyen de faire la même chose sans perte de performances en raison du déréférencement de pointeur?

Je vous remercie.

Ils peuvent être utilisés comme parameters non typés, mais vous devez utiliser la bonne syntaxe.

 struct Foo { void Bar() { // do something } }; template  void Call(TOwner *p) { (p->*func)(); } int main() { Foo a; Call(&a); return 0; } 

En fait, les pointeurs de fonction de membre peuvent être utilisés comme arguments de modèle (exactement comme n’importe quel autre type de pointeur peut être utilisé comme paramètre de modèle):

 struct A { int f(float x); }; template  struct B {}; template struct C; template struct D; 

Toutefois, selon l’extrait suivant de la norme C ++, il est impossible de transmettre des références à des membres.

[temp.param]

  1. Un paramètre de modèle non typé doit avoir l’un des types suivants (éventuellement qualifiés de cv):

(4.1) – type intégral ou énumération,

(4.2) – un pointeur sur un object ou un pointeur sur une fonction,

(4.3) – référence de lvalue à l’object ou référence de lvalue à la fonction,

(4.4) – pointeur sur membre,

(4.5) – std :: nullptr_t.


Ensuite, étant donné que vous avez réussi à transmettre votre type de fonction d’une manière ou d’une autre et que vous souhaitez l’appeler à l’intérieur, vous rencontrez le même problème que si vous souhaitez les stocker dans un pointeur de fonction ou un object std::function : vous devez donc appeler les deux, le fonction membre ainsi que l’object concret. Passer seulement la fonction ne suffira pas.

Mais en fait, vous pouvez réaliser ce que vous voulez. Liez simplement la fonction à votre object et transmettez-la ensuite:

 template void call(T&& t, F&&f) { f(std::forward(t)); } struct A { void foo() { std::cout<<"hello"< 

DEMO