Koenig Lookup , ou Argument Dependent Lookup , décrit comment les noms non qualifiés sont recherchés par le compilateur en C ++.
La norme C ++ 11 § 3.4.2 / 1 stipule:
Lorsque l'expression de suffixe dans un appel de fonction (5.2.2) est un identifiant non qualifié, d'autres espaces de noms non pris en compte lors de la recherche non qualifiée habituelle (3.4.1) peuvent être recherchés, et dans ces espaces de noms, des déclarations de fonction d'ami de portée d'espace de noms ( 11.3) non visibles autrement peuvent être trouvés. Ces modifications de la recherche dépendent des types d'arguments (et pour les arguments de modèle de modèle, de l'espace de noms de l'argument de modèle).
En termes plus simples, Nicolai Josuttis déclare 1 :
Vous n'avez pas besoin de qualifier l'espace de noms pour les fonctions si un ou plusieurs types d'argument sont définis dans l'espace de noms de la fonction.
Un exemple de code simple:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
Dans l'exemple ci-dessus, il n'y a ni using
-declaration ni using
-directive mais le compilateur identifie toujours correctement le nom non qualifié doSomething()
comme la fonction déclarée dans l'espace MyNamespace
de noms en appliquant la recherche Koenig .
Comment ça marche?
L'algorithme dit au compilateur de regarder non seulement la portée locale, mais également les espaces de noms qui contiennent le type de l'argument. Ainsi, dans le code ci-dessus, le compilateur trouve que l'objet obj
, qui est l'argument de la fonction doSomething()
, appartient à l'espace de noms MyNamespace
. Donc, il regarde cet espace de noms pour localiser la déclaration de doSomething()
.
Quel est l'avantage de la recherche Koenig?
Comme le montre l'exemple de code simple ci-dessus, la recherche Koenig offre commodité et facilité d'utilisation au programmeur. Sans la recherche Koenig, il y aurait une surcharge sur le programmeur, pour spécifier à plusieurs reprises les noms using
complets , ou à la place, utiliser de nombreuses déclarations.
Pourquoi la critique de la recherche Koenig?
Une dépendance excessive à la recherche Koenig peut conduire à des problèmes sémantiques et parfois prendre le programmeur au dépourvu.
Prenons l'exemple de std::swap
, qui est un algorithme de bibliothèque standard permettant d'échanger deux valeurs. Avec la recherche Koenig, il faudrait être prudent lors de l'utilisation de cet algorithme car:
std::swap(obj1,obj2);
peut ne pas montrer le même comportement que:
using std::swap;
swap(obj1, obj2);
Avec ADL, la version de la swap
fonction appelée dépend de l'espace de noms des arguments qui lui sont passés.
S'il existe un espace de noms A
et si A::obj1
, A::obj2
& A::swap()
existent, le deuxième exemple entraînera un appel à A::swap()
, ce qui pourrait ne pas être ce que l'utilisateur voulait.
En outre, si pour une raison quelconque les deux A::swap(A::MyClass&, A::MyClass&)
et std::swap(A::MyClass&, A::MyClass&)
sont définis, alors le premier exemple appellera std::swap(A::MyClass&, A::MyClass&)
mais le second ne compilera pas car swap(obj1, obj2)
serait ambigu.
Trivia:
Pourquoi s'appelle-t-il «Koenig lookup»?
Parce qu'il a été conçu par Andrew Koenig, ancien chercheur et programmeur d'AT & T et de Bell Labs .
Lectures complémentaires:
1 La définition de la recherche Koenig est telle que définie dans le livre de Josuttis, The C ++ Standard Library: A Tutorial and Reference .