Pourquoi 'X x; x();' est-il autorisé, quand ' X ' définit une conversion en pointeur de fonction, mais pas, quand il définit une conversion en foncteur?

void f(int){}
typedef void (*f_ptr)(int);

struct Functor{
  void operator()(int){}
};

struct X{
  operator f_ptr(){ return f; }
};

struct Y{
  operator Functor(){ return Functor(); }
};

int main(){
  X x; Y y;
  x(5); // works ?!
  y(5); // doesn't ?!
}

Exemple en direct sur Ideone . Sortie:

Erreur: Aucune correspondance pour l'appel à '(Y) (int) '

Q1: Pourquoi l'appel à x(5) est-il autorisé, même si X ne définit qu'une conversion en pointeur de fonction, et non operator()?

Q2: inversement, pourquoi la même chose n'est-elle pas autorisée, si nous définissons une conversion vers un autre foncteur?

29
demandé sur R. Martinho Fernandes 2012-01-16 00:20:42

1 réponses

x(5); // works ?!

Cela jette implicitement x à un f_ptr et appelle cela. C++11 standard:

§ 13.3.1.1.2 appel à un objet de type de classe [over.appeler.objet]

2) en outre, pour chaque fonction de conversion Non explicite déclarée en T de la forme

operator conversion-type-id ( ) attribute-specifier-seqopt cv-qualifier ;

[...where conversion-type-id indique le type "pointeur vers la fonction de (P1,...,Pn) retour R"...]


y(5); // doesn't ?!

La norme ne mentionne rien sur la conversion implicite en types de classes qui surcharge operator() (aka functors), ce qui implique que le compilateur ne le permet pas.

Vous devez le lancer explicitement:

static_cast<Functor>(y)(5);
26
répondu 2012-01-16 09:54:59