Búsqueda dependiente de argumento
La búsqueda dependiente de argumento, también conocida como ADL (por sus siglas del inglés Argument-Dependent Lookup), o búsqueda de Koenig [1], es el conjunto de reglas para buscar los nombres de función no calificados en las expresiones de llamada a función, incluyendo llamadas a función implícitas a operadores sobrecargados. Estos nombres de función se buscan en los espacios de nombres de sus argumentos además de los ámbitos y espacios de nombres considerados por la búsqueda de nombre no calificado habitual.
La búsqueda dependiente de argumento hace posible el uso de operadores definidos en un espacio de nombres distinto. Ejemplo:
#include <iostream> int main() { std::cout << "Prueba\n"; // No hay operator<< en el espacio de nombres global, pero ADL // examina el espacio de nombres std porque el argumento izquierdo está en // std y encuentra a std::operator<<(std::ostream&, const char*) operator<<(std::cout, "Prueba\n"); // lo mismo, usando la notación de llamada a función // sin embargo, std::cout << endl; // ERROR: 'endl' no está declarado en este espacio de nombres. // Esto no es una llamada a función a endl(), así que ADL no aplica endl(std::cout); // de acuerdo: esta es una llamada a función: ADL examina el espacio de nombres std // porque el argumento de endl está en std, y encuentra a std::endl (endl)(std::cout); // ERROR: 'endl' no está declarado en este espacio de nombres. // La subexpresión (endl) no es una expresión de llamada a función }
Contenido |
[editar] Detalles
Primero, la búsqueda dependiente de argumento no se considera si el conjunto de búsqueda producido por la búsqueda no calificada habitual contiene alguno de los siguientes:
De lo contrario, para cada argumento en una expresión de llamada a función, se examina su tipo para determinar el conjunto asociado de espacios de nombres y clases que se agregará a la búsqueda.
T
o puntero a un array de T
, se examina el tipo T
y su conjunto asociado de clases y espacios de nombres se agrega al conjunto.F
de clase X
, los tipos de parámetro de función, el tipo de retorno de la función, y la clase X
se examinan y su conjunto asociado de clases y espacios de nombres se agregan al conjunto.T
de clase X
, el tipo de miembro y el tipo X
se examinan y su conjunto asociado de clases y espacios de nombres se agrega al conjunto.- Además, si el conjunto de sobrecargas se nombra mediante un id-de-plantilla, todos los argumentos de su tipo y los argumentos de plantilla de plantilla (pero no los argumentos de plantilla de no-tipo) se examina y su conjunto asociado de clases y espacios de nombres se agrega al conjunto.
Si algún espacio de nombres en el conjunto asociado de clases y espacios de nombres es un espacio de nombres en línea, su espacio de nombres circundante también se agrega al conjunto. Si algún espacio de nombres en el conjunto asociado de clases y espacios de nombres contiene directamente un espacio de nombres en línea, ese espacio de nombres en línea se agrega al conjunto. |
(desde C++11) |
Una vez que se determina el conjunto asociado de clases y espacios de nombres, todas las declaraciones que se encuentran en las clases de este conjunto se descartan con el propósito de un procesamiento ADL adicional, excepto las funciones amigas en el ámbito del espacio de nombres y las plantillas de función, como se indica en el punto 2 a continuación.
El conjunto de declaraciones encontradas por la búsqueda no calificada ordinaria y el conjunto de declaraciones que se encuentran en todos los elementos del conjunto asociado producido por ADL, se fusionan, con las siguientes reglas especiales:
[editar] Notas
Esta sección está incompleta |
[editar] Ejemplos
Esta sección está incompleta Razón: más ejemplos |
Ejemplo de http://www.gotw.ca/gotw/030.htm
namespace A { struct X; struct Y; void f(int); void g(X); } namespace B { void f(int i) { f(i); // llama a B::f (recursión infinita) } void g(A::X x) { g(x); // ERROR: ambiguo entre B::g (búsqueda ordinaria) // y A::g (búsqueda dependiente de argumento) } void h(A::Y y) { h(y); // llama a B::h (recursión infinita): ADL examina el espacio de nombres A // pero no encuentra ninguna A::h, así que solo se usa B::h // de la búsqueda ordinaria } }