Pourquoi GCC permet d’appeler cette fonction sans utiliser d’abord son espace de noms?

Dupliquer possible:
Pourquoi la scope des parameters C ++ affecte-t-elle la recherche de fonction dans un espace de noms?

Aujourd’hui, j’ai eu ce comportement étrange. Je peux appeler strangeFn sans using namespace Strange , mais ne permet pas d’appeler strangeFn2 Pourquoi?

 namespace Strange { struct X { }; void strangeFn(X&) {} void strangeFn2(int) {} } int main() { Strange::X x; strangeFn(x); // GCC allows calling this function. strangeFn2(0); // Error: strangeFn2 is not declared in this scope. return 0; } 

Comment les compilateurs C ++ résolvent-ils la scope des symboles?

Ceci s’appelle la recherche dépendante de l’argument (ou la recherche Koenig)

Fondamentalement, si un symbole ne peut pas être résolu, le compilateur examinera le ou les espaces de noms du ou des arguments.

Le second appel de fonction échoue, car strangeFn2 n’est pas visible dans l’espace de noms actuel, ni défini dans l’espace de noms de son type de paramètre ( int ).

Vous pouvez voir comment cela fonctionne bien avec les fonctions d’opérateur:

  std::complex c, d; c += d; // wouldn't really work without ADL 

ou les opérateurs iostream omniprésents:

  std::ssortingng s("hello world"); std::cout << s << std::endl; // Hello world would not compile without ADL... 

Pour le fun, voici à quoi pourrait ressembler hello world sans ADL (et sans mot-clé ...):

  std::ssortingng s("hello world"); std::operator<<(std::cout, s).operator<<(std::endl); // ugly! 

Il existe des cas fantastiques avec ADL et la résolution de surcharge en présence de modèles de fonction, mais je les laisserai en dehors du champ de la réponse pour le moment.