La búsqueda de Koenig , o búsqueda dependiente de argumentos , describe cómo el compilador busca en C ++ nombres no calificados.
El estándar C ++ 11 § 3.4.2 / 1 establece:
Cuando la expresión postfix en una llamada de función (5.2.2) es un id no calificado, se pueden buscar otros espacios de nombres no considerados durante la búsqueda no calificada habitual (3.4.1), y en esos espacios de nombres, declaraciones de función amiga del ámbito de nombres ( 11.3) no se puede ver de otra manera visible. Estas modificaciones a la búsqueda dependen de los tipos de argumentos (y para los argumentos de plantilla, el espacio de nombres del argumento de plantilla).
En términos más simples, Nicolai Josuttis afirma 1 :
No tiene que calificar el espacio de nombres para las funciones si uno o más tipos de argumentos están definidos en el espacio de nombres de la función.
Un ejemplo de código simple:
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass);
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
En el ejemplo anterior, no hay una using
declaración ni una using
directiva, pero el compilador identifica correctamente el nombre no calificado doSomething()
como la función declarada en el espacio MyNamespace
de nombres mediante la aplicación de búsqueda de Koenig .
¿Como funciona?
El algoritmo le dice al compilador que no solo mire el alcance local, sino también los espacios de nombres que contienen el tipo de argumento. Por lo tanto, en el código anterior, el compilador encuentra que el objeto obj
, que es el argumento de la función doSomething()
, pertenece al espacio de nombres MyNamespace
. Entonces, mira ese espacio de nombres para ubicar la declaración de doSomething()
.
¿Cuál es la ventaja de la búsqueda de Koenig?
Como lo demuestra el sencillo ejemplo de código anterior, la búsqueda de Koenig proporciona comodidad y facilidad de uso al programador. Sin la búsqueda de Koenig, habría una sobrecarga en el programador, para especificar repetidamente los nombres completos o, en su lugar, utilizar numerosas using
declaraciones.
¿Por qué la crítica de la búsqueda de Koenig?
La excesiva dependencia de la búsqueda de Koenig puede conducir a problemas semánticos y, a veces, pillar desprevenido al programador.
Considere el ejemplo de std::swap
, que es un algoritmo de biblioteca estándar para intercambiar dos valores. Con la búsqueda de Koenig, uno debería ser cauteloso al usar este algoritmo porque:
std::swap(obj1,obj2);
puede no mostrar el mismo comportamiento que:
using std::swap;
swap(obj1, obj2);
Con ADL, qué versión de la swap
función se llama dependería del espacio de nombres de los argumentos que se le pasan.
Si existe un espacio de nombres A
y A::obj1
, A::obj2
y A::swap()
existe, el segundo ejemplo dará como resultado una llamada a A::swap()
, que podría no ser lo que el usuario quería.
Además, si por alguna razón tanto A::swap(A::MyClass&, A::MyClass&)
y std::swap(A::MyClass&, A::MyClass&)
se definen, a continuación, el primer ejemplo llamará std::swap(A::MyClass&, A::MyClass&)
pero el segundo no se compilará porque swap(obj1, obj2)
sería ambiguo.
Trivialidades:
¿Por qué se llama "búsqueda de Koenig"?
Porque fue ideado por el ex investigador y programador de AT&T y Bell Labs, Andrew Koenig .
Otras lecturas:
1 La definición de búsqueda de Koenig es como se define en el libro de Josuttis, The C ++ Standard Library: A Tutorial and Reference .