Koenig Lookup oder Argument Dependent Lookup beschreibt, wie unqualifizierte Namen vom Compiler in C ++ gesucht werden.
Der C ++ 11-Standard § 3.4.2 / 1 besagt:
Wenn der Postfix-Ausdruck in einem Funktionsaufruf (5.2.2) eine unqualifizierte ID ist, können andere Namespaces durchsucht werden, die bei der üblichen unqualifizierten Suche (3.4.1) nicht berücksichtigt wurden, und in diesen Namespaces Namespace-Scope-Friend-Funktionsdeklarationen ( 11.3) kann sonst nicht sichtbar gefunden werden. Diese Änderungen an der Suche hängen von den Argumenttypen ab (und bei Vorlagenvorlagenargumenten vom Namespace des Vorlagenarguments).
Einfacher ausgedrückt sagt Nicolai Josuttis 1 :
Sie müssen den Namespace nicht für Funktionen qualifizieren, wenn im Namespace der Funktion ein oder mehrere Argumenttypen definiert sind.
Ein einfaches Codebeispiel:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
Im obigen Beispiel gibt es weder eine using
-deklaration noch eine using
-directive, aber der Compiler identifiziert den nicht qualifizierten Namen korrekt doSomething()
als die im Namespace deklarierte Funktion, MyNamespace
indem er die Koenig-Suche anwendet .
Wie funktioniert es?
Der Algorithmus weist den Compiler an, nicht nur den lokalen Bereich zu betrachten, sondern auch die Namespaces, die den Typ des Arguments enthalten. Somit stellt der Compiler im obigen Code fest, dass das Objekt obj
, das das Argument der Funktion ist doSomething()
, zum Namespace gehört MyNamespace
. Es sieht sich also diesen Namespace an, um die Deklaration von zu finden doSomething()
.
Was ist der Vorteil der Koenig-Suche?
Wie das obige einfache Codebeispiel zeigt, bietet die Koenig-Suche dem Programmierer Komfort und Benutzerfreundlichkeit. Ohne Koenig-Suche würde der Programmierer einen Overhead haben, um die vollständig qualifizierten Namen wiederholt anzugeben oder stattdessen zahlreiche using
Deklarationen zu verwenden.
Warum die Kritik an Koenig Lookup?
Übermäßiges Vertrauen in die Koenig-Suche kann zu semantischen Problemen führen und den Programmierer manchmal überraschen.
Betrachten Sie das Beispiel std::swap
eines Standardbibliotheksalgorithmus zum Austauschen von zwei Werten. Bei der Koenig-Suche müsste man bei der Verwendung dieses Algorithmus vorsichtig sein, weil:
std::swap(obj1,obj2);
zeigt möglicherweise nicht das gleiche Verhalten wie:
using std::swap;
swap(obj1, obj2);
Bei ADL swap
hängt die Version der aufgerufenen Funktion vom Namespace der an ADL übergebenen Argumente ab.
Wenn es einen Namespace gibt A
und wenn A::obj1
, A::obj2
& A::swap()
existiert, führt das zweite Beispiel zu einem Aufruf von A::swap()
, was möglicherweise nicht das ist, was der Benutzer wollte.
Wenn aus irgendeinem Grund beide A::swap(A::MyClass&, A::MyClass&)
und std::swap(A::MyClass&, A::MyClass&)
definiert sind, wird das erste Beispiel aufgerufen std::swap(A::MyClass&, A::MyClass&)
, das zweite jedoch nicht kompiliert, da swap(obj1, obj2)
dies mehrdeutig wäre.
Wissenswertes:
Warum heißt es "Koenig Lookup"?
Weil es vom ehemaligen Forscher und Programmierer Andrew Koenig von AT & T und Bell Labs entwickelt wurde .
Weiterführende Literatur:
1 Die Definition von Koenig Lookup ist wie in Josuttis 'Buch The C ++ Standard Library: A Tutorial and Reference definiert .