2014-06-11 2 views
2

Je pense que cet exemple illustre le mieux ma question:Existe-t-il des règles différentes concernant les conflits ADL ou de dénomination en ce qui concerne les opérateurs surchargés?

namespace N { 

    class C { 
    public: 
     friend bool operator==(const C& c, const C& x) { 
      return true; 
     } 
     friend bool f(const C& c, const C& x) { 
      return true; 
     } 
    }; 

    class D { 
    public: 
     bool operator==(const D& x) { 
      bool a = C{} == C{};  // this works 
      return true; 
     } 
     bool f(const D& x) { 
      bool a = f(C{}, C{});  // this does not work 
      return true; 
     } 
    }; 
} 

Je l'ai toujours vu comme étant surchargées opérateurs comme fonction, sauf pour la « syntaxe d'appel » si vous voulez. J'ai juste noté la différence ci-dessus cependant dans ADL ou les règles de recherche de nom (je ne sais pas lequel).

Quelqu'un peut-il expliquer pourquoi le bool operator==(const C& c, const C& x) est trouvé mais pas le bool f(const C& c, const C& x)?

+0

Notez que ce cache, pas ADL, puisque tout est dans le même espace. ADL consiste à rechercher la fonction dans des espaces de noms supplémentaires * (en particulier, les espaces de noms dans lesquels les types de paramètres sont définis). –

Répondre

2

Votre D::f est cachantC::f; si vous renommez ce dernier à C::g et ajustez l'appel alors cela fonctionne bien (montrant que la fonction peut être trouvé et a accédé juste).

Votre code n'appelle pas directement les fonctions de l'opérateur, mais cela est fait pour vous par la langue. Par conséquent, vous n'utilisez pas le nom de la fonction opérateur, de sorte qu'aucune dissimulation de nom ne s'applique.

Si vous écrivez operator==(C{}, C{}) (au lieu de C{} == C{}), alors vous verrez le même comportement que f(C{}, C{}) (demo). Donc, quand vous dites: "J'ai toujours vu les opérateurs surchargés comme des fonctions, à l'exception de la" syntaxe d'appel "si vous voulez", vous avez déjà mis le doigt sur la tête.


Voici quelques standardese pour vous:

[C++11: 13.5/4]: fonctions de l'opérateur ne sont généralement pas appelés directement; à la place, ils sont invoqués pour évaluer les opérateurs qu'ils implémentent (13.5.1 - 13.5.7). Ils peuvent cependant être appelés explicitement en utilisant l'opérateur-fonction-id comme nom de la fonction dans la syntaxe d'appel de fonction (5.2.2). [Exemple:

complex z = a.operator+(b); // complex z = a+b; 
void* p = operator new(sizeof(int)*n); 

exemple -fin]

[C++11: 3.3.7/4]:[..] 4) Un nom déclaré dans une fonction membre cache une déclaration du même nom, dont la portée étend ou après la fin de la classe de la fonction membre. [..]

[C++11: 3/4]: un nom est une utilisation d'un identificateur (2,11), opérateur-fonction-id (13,5), littéral-opérateur-id (13.5.8), conversion-function-id (12.3.2), ou numéro de modèle (14.2) qui indique une entité ou étiquette (6.6.4, 6.1).

(Le [qualifié] opérateur-fonction-id ici est ::N::C::operator==.)

Questions connexes