¿Qué es la "búsqueda dependiente de argumentos" (también conocida como ADL o "búsqueda Koenig")?

Resuelto user965369 asked hace 12 años • 4 respuestas

¿Cuáles son algunas buenas explicaciones sobre qué es la búsqueda dependiente de argumentos? Mucha gente también lo llama Koenig Lookup.

Preferiblemente me gustaría saber:

  • ¿Por qué es algo bueno?
  • ¿Por qué es algo malo?
  • ¿Como funciona?
user965369 avatar Nov 13 '11 19:11 user965369
Aceptado

La búsqueda dependiente de argumentos (ADL), a veces denominada búsqueda Koenig , describe cómo el compilador busca nombres no calificados en C++.

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 una identificación no calificada, 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 funciones amigas de alcance de espacio de nombres ( 11.3) que de otro modo no serían visibles. 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 es necesario calificar el espacio de nombres para 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 ni una usingdeclaración ni una usingdirectiva, pero aun así el compilador identifica correctamente el nombre no calificado doSomething()como la función declarada en el espacio de nombres MyNamespacemediante la aplicación de ADL.

¿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. Así, 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 ADL?

Como lo demuestra el ejemplo de código simple anterior, ADL brinda comodidad y facilidad de uso al programador. Sin ADL habría una sobrecarga para el programador al tener que especificar repetidamente los nombres completos o, en su lugar, utilizar numerosas usingdeclaraciones.

¿Por qué las críticas a la ADL?

La dependencia excesiva de ADL puede provocar problemas semánticos y, a veces, tomar desprevenido al programador.

Considere el ejemplo de std::swap, que es un algoritmo de biblioteca estándar para intercambiar dos valores. Con la ADL habría que tener cuidado al utilizar este algoritmo porque:

std::swap(obj1,obj2);

puede no mostrar el mismo comportamiento que:

using std::swap;
swap(obj1, obj2);

Con ADL, la versión de swapla función que se llama dependerá del espacio de nombres de los argumentos que se le pasan.

Si existe un espacio de nombres Ay si A::obj1, A::obj2y A::swap()existen, entonces 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 ambos A::swap(A::MyClass&, A::MyClass&)y std::swap(A::MyClass&, A::MyClass&)están definidos, entonces 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é a veces se le llama “búsqueda Koenig”?

Porque fue ideado por el ex investigador y programador de AT&T y Bell Labs, Andrew Koenig , aunque el propio Koenig lo cuestiona en una publicación de blog de 2012 :

La razón por la que mi nombre está asociado con la búsqueda dependiente de argumentos es que, aunque no inventé la idea, sí reconocí que la introducción de espacios de nombres causa un problema grave que era necesario resolver con ADL, o algo similar.

Otras lecturas:

  • Búsqueda del nombre de Herb Sutter en GotW

  • Estándar C++ 03/11 [basic.lookup.argdep]: 3.4.2 Búsqueda de nombres dependiente de argumentos.


** 1 ** La definición de ADL es la que se define en el libro de Josuttis, *La biblioteca estándar de C++: un tutorial y una referencia*.
Alok Save avatar Nov 13 '2011 13:11 Alok Save

En Koenig Lookup, si se llama a una función sin especificar su espacio de nombres, entonces el nombre de una función también se busca en los espacios de nombres en los que se define el tipo de argumento. Por eso también se le conoce como búsqueda de nombres dependiente de argumentos , en pocas palabras simplemente ADL .

Es gracias a Koenig Lookup que podemos escribir esto:

std::cout << "Hello World!" << "\n";

En caso contrario tendríamos que escribir:

std::operator<<(std::operator<<(std::cout, "Hello World!"), "\n");

¡Lo cual realmente es escribir demasiado y el código se ve muy feo!

En otras palabras, en ausencia de Koenig Lookup, incluso un programa Hello World parece complicado.

Sarfaraz Nawaz avatar Nov 13 '2011 13:11 Sarfaraz Nawaz