为什么'std :: endl'在语句'std :: cout<<中使用时需要命名空间限定std :: endl;“,给定参数依赖查找?

时间:2014-01-04 20:16:21

标签: c++ argument-dependent-lookup

我正在查看argument-dependent lookup上的维基百科条目,并且(2014年1月4日)给出了以下示例:

#include<iostream>

int main() 
{
  std::cout << "Hello World, where did operator<<() come from?" << std::endl;
}

...以下评论:

  

请注意,std :: endl是一个函数,但需要完全限定,   因为它被用作运算符的参数&lt;&lt; (std :: endl是一个函数   指针,而不是函数调用。)

我的想法是评论不正确(或根本不清楚)。我正在考虑更改评论,而不是

  

请注意,std :: endl需要完全限定,   因为ADL不适用于函数调用的参数;它   仅适用于函数名称本身。

我是否认为维基百科的评论不正确?我建议的改变是否正确? (即,在这个例子中,我对ADL的理解是正确的吗?)

3 个答案:

答案 0 :(得分:10)

维基百科的说法没有错。

std::cout << "Hello World, where did operator<<() come from?" << std::endl

等同于以下(假设operator<<实现为自由函数)

operator<<(
    operator<<(std::cout, "Hello World, where did operator<<() come from?"),
    std::endl)

显然需要coutendl的命名空间限定,因为这是依赖于参数的查找(函数),而不是“参数查找”< / em>的。
参数决定了要调用的函数,而不是方法。

答案 1 :(得分:3)

原始短语和你的短语都是正确的。

std::endl 是一个功能。 C++03 spec section 27.6 [lib.iostream.format]

  

标题<ostream>简介

namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ostream;
typedef basic_ostream<char> ostream;
typedef basic_ostream<wchar_t> wostream;
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
...

在此上下文中,std::endl函数(或更确切地说,它衰减的函数指针)作为参数传递给operator<<。由于它是一个参数,ADL不适用。

答案 2 :(得分:1)

维基百科条目是正确的。 operator<<命名空间中std个操作数之一的事实导致名称查找包括来自命名空间operator<<的{​​{1}}声明分辨率。