Bjarne是错误的这个ADL的例子,还是我有一个编译器错误?
我正在阅读关于参数相关查找 的C ++编程语言第4版 (由Bjarne Stroustrup撰写 )。 这里是引用(26.3.6,过度的ADL):
依赖于参数的查找(通常称为ADL)对于避免冗长是非常有用的(14.2.4)。 例如:
#include <iostream> int main() { std::cout << "Hello, world" << endl; // OK because of ADL }没有依赖于参数的查找,
endl操纵器将不会被发现。 实际上,编译器注意到<<的第一个参数是std定义的一个ostream。 因此,它在std查找endl并find它(在<iostream>)。
这里是编译器(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; ^ 
这是编译器或书中的一个错误。 标准说什么?
更新:
 我需要澄清一点。 我知道正确的答案是使用std::endl 。 问题是关于书中的文字。 正如Lachlan Easton所说,这不仅仅是一个错字。 整个段落(可能)是错误的。 我可以接受这种错误,如果这本书是由其他(不知名的)作者,但我是(现在仍然)怀疑,因为它是由Bjarne写的。 
 这不是编译器中的错误。  ADL用于查找函数而不是参数 。  operator<<是通过查看参数std::cout和(应该是什么) std::endl通过ADLfind的函数。 
对于那些说这是一个错字,事实并非如此。 Bjarne犯了一个错误,或者编译器错了。 OP发布的一段后面的段落是这样写的
没有依赖于参数的查找,endl操纵器将不会被发现。 实际上,编译器注意到<<的第一个参数是std中定义的一个ostream。 因此,它在std中查找endl并find它(在
<iostream>)。
  这是其他人已经指出的书中的一个错字。  但是,这本书的意思是 我们必须写 
 std::operator<<(std::cout, "Hello, world").operator<<(std::endl); 
没有ADL。 这就是Bjarne冗长的意思。
我纠正了。 正如Lachlan Easton所指出的那样,这不是一个错字,而是一个错误 。 我无法访问这本书,这就是为什么我无法阅读这个段落并自己意识到这一点。 我已经把这个错误报告给了Bjarne,以便他能纠正它。
滑稽。 维基百科上也有同样的例子
请注意,
std::endl是一个函数,但它需要充分的限定,因为它被用作operator<<(std::endl是一个函数指针,而不是函数调用)的参数。
 毫无疑问,这是书中的一个错误。 然而,例子std::operator<<(std::cout, "Hello, world").operator<<(std::endl); 显示ADL如何帮助减less冗长。 
感谢gx_ 指出我的错误 。
提示的名称是“依赖于参数的查找”。
它是查找不合格的函数名称,这取决于 参数 。
这与查询争论没有任何关系。
Bjarne错过了。
 我没有这本书,但是这似乎是本书中的一个错误,它缺less命名空间限定符的事实与ADL无关。 它应该是std::endl 。 
 是的,这是一个错误 – 这个例子是不合格的,不应该编译。  ADL适用于引入函数调用expression式的非限定函数名称。  endl是一个试图查找std::endl的idexpression式。  endl不会引入函数调用expression式,所以不使用依赖于参数的查找,只使用非限定查找,因此不会像预期的那样findstd::endl 。 
一个更简单和正确的例子是:
 #include <vector> int main() { std::vector<int> x, y; swap(x,y); // calls std::swap due to ADL } 
 总之,在查找具有不合格id(例如f )的函数调用(例如f(x,y,z) )之前,首先分析函数的参数(例如x,y,z )以确定它们的types。 关联的名称空间的列表是基于types形成的(例如,types定义的封闭名称空间是关联的名称空间)。 这些命名空间然后另外searchfunction。 
  Bjarne的例子的目的是炫耀std::operator<< function的ADL,而不是std::endl 。 这需要额外的理解,即重载操作符实际上是函数调用expression式,所以x << y表示operator<<(x,y) ,而operator<<是非限定名称,因此ADL适用于它。  LHS的types是std::ostream所以std是一个关联的命名空间,因此find了std::operator<<(ostream&, ...) 。 
更正后的注释应为:
没有依赖于参数的查找,
std命名空间中的重载的<<运算符将不会被find。 实际上,编译器注意到<<的第一个参数是std中定义的一个ostream。 因此,它在std中查找运算符<<并find它(在<iostream>)。