Estoy leyendo The C ++ Programming Language, 4th Edition (por Bjarne Stroustrup ) sobrebúsqueda-dependiente de argumento. Aquí está la cita (26.3.6, ADL demasiado agresivo):
La búsqueda dependiente de argumentos (a menudo denominada ADL) es muy útil para evitar la verbosidad (14.2.4). Por ejemplo:
#include <iostream> int main() { std::cout << "Hello, world" << endl; // OK because of ADL }
Sin la búsqueda dependiente de argumentos,
endl
no se encontraría el manipulador. Tal como está, el compilador se da cuenta de que el primer argumento de<<
estáostream
definido enstd
. Por tanto, buscaendl
enstd
y lo encuentra (en<iostream>
).
Y aquí está el resultado producido por el compilador (modo C ++ 11):
prog.cpp: In function ‘int main()’:
prog.cpp:4:36: error: ‘endl’ was not declared in this scope
std::cout << "Hello, world" << endl;
^
O esto es un error en el compilador o en el libro. ¿Qué dice la norma?
Actualizar:
Necesito aclarar un poco. Sé que la respuesta correcta es usar std::endl
. La pregunta era sobre el texto del libro. Como ya dijo Lachlan Easton , no es solo un error tipográfico. Todo el párrafo está (probablemente) mal. Puedo aceptar este tipo de error si el libro es de otro autor (menos conocido), pero tenía (y todavía tengo) dudas porque fue escrito por Bjarne.
fuente
std::endl
no bugstd::
no es necesario en este caso, debido a ADL. Pero esto no se compila, de ahí la pregunta.Respuestas:
No es un error en el compilador. ADL se utiliza para buscar funciones, no argumentos .
operator<<
es la función encontrada a través de ADL aquí mirando los parámetrosstd::cout
y (lo que debería ser)std::endl
.fuente
std::endl
es de hecho (y confusamente) una función:endl(std::cout << "Hello, world"); // OK because of ADL
Para aquellos que dicen que es un error tipográfico, no lo es. O Bjarne cometió un error o el compilador lo hizo mal. El párrafo después del publicado por OP dice
fuente
<iostream>
)".Es un error tipográfico en el libro, como ya han señalado los demás. Sin embargo, lo que se quiere decir en el libro es quetendríamos que escribirstd::operator<<(std::cout, "Hello, world").operator<<(std::endl);
sin ADL. Eso es lo que Bjarne quiso decir con verbosidad.
Me quedo corregido. Como señala Lachlan Easton , no es un error tipográfico, sino un error en el libro. No tengo acceso a este libro, por eso no pude leer ese párrafo y darme cuenta yo mismo. He informado de este error a Bjarne para que pueda corregirlo.
Gracioso. El mismo ejemplo está en Wikipedia y
Sin duda, es un error del libro. Sin embargo, el ejemplo
std::operator<<(std::cout, "Hello, world").operator<<(std::endl);
muestra cómo la ADL ayuda a reducir la verbosidad.Gracias a gx_ por señalar mi error .
fuente
std::operator<<
ocurre la búsqueda ) y escribió un párrafo completo con información incorrecta. Realmente te hace creer que las reglas de ADL cambiaron y que los compiladores ahora no funcionan.std::operator<<(std::cout, "Hello, world").operator<<(std::endl);
(ver no miembrooperator<<
y miembrooperator<<
)La sugerencia está en el nombre "búsqueda dependiente del argumento".
Es una búsqueda de nombres de funciones no calificados, que funciona según los argumentos .
No tiene nada que ver con la búsqueda de argumentos.
Bjarne se equivocó.
fuente
No tengo el libro, pero esto parece ser un error en el libro, el hecho de que falte el calificador de espacio de nombres no tiene nada que ver con ADL. Debería serlo
std::endl
.fuente
std::cout
) Él estaba hablando de buscaroperator<<
, noendl
.Sí, es un error: el ejemplo está mal formado y no debería compilarse. ADL se aplica a nombres de funciones no calificados que introducen expresiones de llamada de función.
endl
es una expresión de identificación que intenta buscarstd::endl
.endl
no introduce una expresión de llamada de función, por lo que la búsqueda dependiente de argumentos no se usa para ella, solo se usa una búsqueda no calificada, por lo que no encontrarástd::endl
como se esperaba.Un ejemplo más simple y correcto sería:
#include <vector> int main() { std::vector<int> x, y; swap(x,y); // calls std::swap due to ADL }
En resumen, antes de buscar una llamada de función (p
f(x,y,z)
. Ej. ) Con un id no calificado (pf
. Ej. ), Primerox,y,z
se analizan los parámetros de la función (p . Ej. ) Para determinar su tipo. Se forma una lista de espacios de nombres asociados en función de los tipos (por ejemplo, el espacio de nombres adjunto de la definición del tipo es un espacio de nombres asociado). Estos espacios de nombres se buscan adicionalmente para la función.La intención del ejemplo de Bjarne es mostrar la ADL de la
std::operator<<
función, y nostd::endl
. Esto requiere una comprensión adicional de que los operadores sobrecargados son, de hecho, expresiones de llamada de función, esx << y
deciroperator<<(x,y)
, yoperator<<
es un nombre no calificado, y por lo tanto ADL se aplica a él. El tipo de la LHS esstd::ostream
así questd
es un espacio de nombres asociado, y por lo tantostd::operator<<(ostream&, ...)
se encuentra.El comentario corregido debe leer:
fuente