7

我正在查看有关参数依赖查找的 Wikipedia 条目,并且(2014 年 1 月 4 日)给出了以下示例:

#include<iostream>

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

...带有以下评论:

请注意,std::endl 是一个函数,但它需要完全限定,因为它用作 operator<< 的参数(std::endl 是函数指针,而不是函数调用)。

我的想法是评论不正确(或根本不清楚)。我正在考虑将评论改为说

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

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

4

3 回答 3

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因为这是(函数的)参数相关查找,而不是“参数查找”
参数确定要调用的函数,而不是方法。

于 2014-01-04T20:20:42.057 回答
3

原来的措辞和你的措辞都是正确的。

std::endl 一个函数。C++03 规范第 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 不适用。

于 2014-01-04T20:23:56.407 回答
1

维基百科条目是正确的。operator<<' 的操作数之一在命名空间中这一事实std导致名称查找在提供给重载解析的候选声明集中包含operator<<来自命名空间的声明。std

于 2014-01-04T20:20:57.497 回答