Notez que intégré operator& renverra un prvalue de type T*
. Donc, &foo
retournera un pointeur de fonction avec le type void (*)()
, qui est une prvalue et ne peut pas être lié à lvalue référence à non-const; c'est exactement ce que bind()
attend en tant que paramètre, puis il échoue.
Pour bind(foo)
, modèle pamareter F
sera déduit que le type de fonction exactement (à savoir void()
), le type d'argument de bind
sera void(&)()
, donc il fonctionne.
Vous pourriez penser que foo
et &foo
devraient avoir le même effet en raison de la décroissance de la fonction-à-pointeur. Mais notez que le paramètre bind()
est déclaré en tant que passage par référence. Alors pour le bind(foo)
, la désintégration fonction-à-pointeur ne se produit pas, c'est pourquoi le type d'argument est déduit comme référence à la fonction. D'autre part, pour bind(&foo)
, operator&
est appelée explicitement pour renvoyer un pointeur de fonction prvalue, qui ne peut pas être passé à bind()
.
Si le paramètre est déclaré comme valeur de transfert, la désintégration fonction-à-pointeur se produit, alors bind(foo)
et bind(&foo)
auraient le même effet et les deux fonctionneraient correctement.
void foo();
template <typename F> void bind(F);
bind(foo); // OK, F=void(*)()
bind(&foo); // same as above
Même raison que pour int int; void bind (int &); ': Vous pouvez dire' bind (a) 'mais pas' bind (& a) '. –