Koenig Lookup , o Argument Dependent Lookup , descrive come i nomi non qualificati vengono cercati dal compilatore in C ++.
Lo standard C ++ 11 § 3.4.2 / 1 afferma:
Quando l'espressione postfisso in una chiamata di funzione (5.2.2) è un ID non qualificato, è possibile ricercare altri spazi dei nomi non considerati durante la normale ricerca non qualificata (3.4.1) e, in tali spazi dei nomi, dichiarazioni di funzione amico dello spazio dei nomi ( 11.3) non altrimenti visibile può essere trovato. Queste modifiche alla ricerca dipendono dai tipi di argomenti (e per gli argomenti del modello di modello, lo spazio dei nomi dell'argomento del modello).
In termini più semplici Nicolai Josuttis afferma 1 :
Non è necessario qualificare lo spazio dei nomi per le funzioni se uno o più tipi di argomenti sono definiti nello spazio dei nomi della funzione.
Un semplice esempio di codice:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
Nell'esempio precedente non esiste né una using
dichiarazione né una using
direttiva, ma il compilatore identifica correttamente il nome non qualificato doSomething()
come funzione dichiarata nello spazio MyNamespace
dei nomi applicando la ricerca Koenig .
Come funziona?
L'algoritmo dice al compilatore di guardare non solo all'ambito locale, ma anche agli spazi dei nomi che contengono il tipo di argomento. Pertanto, nel codice precedente, il compilatore rileva che l'oggetto obj
, che è l'argomento della funzione doSomething()
, appartiene allo spazio dei nomi MyNamespace
. Quindi, cerca quello spazio dei nomi per individuare la dichiarazione di doSomething()
.
Qual è il vantaggio della ricerca Koenig?
Come dimostra il semplice esempio di codice sopra riportato, la ricerca Koenig offre praticità e facilità d'uso al programmatore. Senza la ricerca di Koenig ci sarebbe un sovraccarico sul programmatore, per specificare ripetutamente i nomi pienamente qualificati o, invece, usare numerose using
dichiarazioni.
Perché le critiche alla ricerca di Koenig?
L'eccessiva dipendenza dalla ricerca di Koenig può portare a problemi semantici e talvolta sorprendere il programmatore.
Considera l'esempio di std::swap
, che è un algoritmo di libreria standard per scambiare due valori. Con la ricerca Koenig si dovrebbe essere cauti durante l'utilizzo di questo algoritmo perché:
std::swap(obj1,obj2);
potrebbe non mostrare lo stesso comportamento di:
using std::swap;
swap(obj1, obj2);
Con ADL, quale versione della swap
funzione viene chiamata dipende dallo spazio dei nomi degli argomenti passati ad essa.
Se esiste uno spazio dei nomi A
e se A::obj1
, A::obj2
ed A::swap()
esiste, il secondo esempio si tradurrà in una chiamata A::swap()
, che potrebbe non essere quella desiderata dall'utente.
Inoltre, se per qualche motivo entrambi A::swap(A::MyClass&, A::MyClass&)
e std::swap(A::MyClass&, A::MyClass&)
sono definiti, il primo esempio chiamerà std::swap(A::MyClass&, A::MyClass&)
ma il secondo non verrà compilato perché swap(obj1, obj2)
sarebbe ambiguo.
curiosità:
Perché si chiama "ricerca Koenig"?
Perché è stato ideato dall'ex ricercatore e programmatore AT&T e Bell Labs, Andrew Koenig .
Ulteriori letture:
1 La definizione della ricerca Koenig è come definita nel libro di Josuttis, The C ++ Standard Library: A Tutorial and Reference .