stringtranslate.com

Búsqueda de nombres dependiente de argumentos

En el lenguaje de programación C++ , la búsqueda dependiente de argumentos ( ADL ), o búsqueda de nombre dependiente de argumentos , [1] se aplica a la búsqueda de un nombre de función no calificado según los tipos de argumentos proporcionados a la llamada de función . Este comportamiento también se conoce como búsqueda de Koenig , ya que a menudo se atribuye a Andrew Koenig , aunque él no es su inventor. [2]

Durante la búsqueda dependiente de argumentos, se pueden buscar otros espacios de nombres que no se consideran durante la búsqueda normal, donde el conjunto de espacios de nombres que se buscarán depende de los tipos de argumentos de la función. Específicamente, el conjunto de declaraciones descubiertas durante el proceso ADL, y consideradas para la resolución del nombre de la función, es la unión de las declaraciones encontradas por la búsqueda normal con las declaraciones encontradas al buscar en el conjunto de espacios de nombres asociados con los tipos de argumentos de la función.

Ejemplo

Un ejemplo de ADL se ve así:

espacio de nombres NS {  clase A {};  vacío f ( A & a , int i ) {}     } // espacio de nombres NS int main () { NS :: A a ; f ( a , 0 ); // Llama a NS::f. }       

A pesar de que elprincipalLa función no está en el espacio de nombres NS, ni el espacio de nombres NS está en el alcance, la funciónNS::f(A&, entero)se encuentra debido a los tipos declarados de los argumentos reales en la declaración de llamada de función.

Un patrón común en la biblioteca estándar de C++ es declarar operadores sobrecargados que se encontrarán de esta manera. Por ejemplo, este sencillo programa Hola mundo no se compilaría si no fuera por ADL:

#include <iostream> #include <cadena>  int main () { std :: string str = "hola mundo" ; std :: cout << str ; }         

Usar <<equivale a llamar operator<<sin el std::calificador. Sin embargo, en este caso, la sobrecarga del operador << que funciona para stringestá en el stdespacio de nombres, por lo que se requiere ADL para su uso.

El siguiente código funcionaría sin ADL (que se le aplica de todos modos):

#include <flujo de datos> int principal () { std :: cout << 5 ; }     

Funciona porque el operador de salida para números enteros es una función miembro de la std::ostreamclase, que es del tipo cout. Por lo tanto, el compilador interpreta esta declaración como

std :: cout.operador << ( 5 ) ;

que puede resolverse durante una búsqueda normal. Sin embargo, tenga en cuenta que, por ejemplo, la función const char *sobrecargada operator<<es una función que no es miembro del stdespacio de nombres y, por lo tanto, requiere ADL para una búsqueda correcta:

/* imprimirá la cadena de caracteres proporcionada como se esperaba utilizando ADL derivado del tipo de argumento std::cout */ operador << ( std :: cout , "Hola" ) /* llama a una función miembro ostream del operador<< tomando una constante void*, que imprimirá la dirección de la cadena de caracteres proporcionada en lugar del contenido de la cadena de caracteres */ std :: cout . operator << ( "Hola" ) 

La función stdno miembro sobrecargada del espacio de nombres operator<<para manejar cadenas es otro ejemplo:

/*equivalente al operador<<(std::cout, str). El compilador busca el espacio de nombres std utilizando ADL debido al tipo std::string del parámetro str y std::cout */ std :: cout << str ;  

Como señala Koenig en una nota personal, [2] sin ADL el compilador indicaría un error indicando que no pudo encontrarlo operator<<, ya que la declaración no especifica explícitamente que se encuentra en el stdespacio de nombres.

Interfaces

Las funciones encontradas por ADL se consideran parte de la interfaz de una clase. En la biblioteca estándar de C++, varios algoritmos utilizan llamadas no calificadas a swapfrom dentro del stdespacio de nombres. Como resultado, std::swapse utiliza la función genérica si no se encuentra nada más, pero si estos algoritmos se utilizan con una clase de terceros, Foo, que se encuentra en otro espacio de nombres que también contiene , se utilizará swap(Foo&, Foo&)esa sobrecarga de .swap

Crítica

Si bien ADL hace que sea práctico que las funciones definidas fuera de una clase se comporten como si fueran parte de la interfaz de esa clase, hace que los espacios de nombres sean menos estrictos y, por lo tanto, pueden requerir el uso de nombres completamente calificados cuando, de lo contrario, no serían necesarios. Por ejemplo, la biblioteca estándar de C++ hace un uso extensivo de llamadas no calificadas a std::swappara intercambiar dos valores. La idea es que, luego, uno puede definir una versión propia de swapen su propio espacio de nombres y se usará dentro de los algoritmos de la biblioteca estándar. En otras palabras, el comportamiento de

espacio de nombres N {  estructura A {};  } // espacio de nombres N Una a ; Una b ;  std :: swap ( a , b ); 

Puede o no ser el mismo que el comportamiento de

usando std :: swap ; swap ( a , b );  

(donde ay bson de tipo N::A) porque si N::swap(N::A&, N::A&)existe, el segundo de los ejemplos anteriores lo llamará mientras que el primero no. Además, si por alguna razón se definen tanto N::swap(N::A&, N::A&)como , entonces el primer ejemplo llamará pero el segundo no se compilará porque sería ambiguo.std::swap(N::A&, N::A&)std::swap(N::A&, N::A&)swap(a, b)

En general, la dependencia excesiva de ADL puede generar problemas semánticosL1 . Si una biblioteca, , espera que las llamadas no calificadas a foo(T)tengan un significado y otra biblioteca, L2espera que tenga otro, entonces los espacios de nombres pierden su utilidad. Sin embargo, si , L1espera L1::foo(T)tener un significado y L2hace lo mismo, entonces no hay conflicto, pero las llamadas a foo(T)tendrían que estar completamente calificadas (es decir, L1::foo(x)en contraposición a using L1::foo; foo(x);) para que ADL no interfiera.

Referencias

  1. ^ "Borrador de trabajo, estándar para el lenguaje de programación C++" (PDF) . JTC1/SC22/WG21 . 19 de octubre de 2005. Capítulo 3.4.2 – Búsqueda de nombres dependiente de argumentos – p. 2. Archivado desde el original (PDF) el 14 de diciembre de 2005 . Consultado el 13 de marzo de 2012 .
  2. ^ ab "Una nota personal sobre la búsqueda dependiente de argumentos". 3 de mayo de 2012. Archivado desde el original el 17 de marzo de 2018. Consultado el 7 de febrero de 2014 .

Enlaces externos