为什么在语句"std::cout << std::endl;"中使用时需要命名空间限定,给定依赖于参数的查找?
Why does 'std::endl' require the namespace qualification when used in the statement 'std::cout << std::endl;", given argument-dependent lookup?
我正在查看维基百科关于参数依赖查找的条目,并且(2014年1月4日)给出了以下示例:
#include<iostream>
int main()
{
std::cout << "Hello World, where did operator<<() come from?" << std::endl;
}
。并附有以下评论:
请注意,std::endl 是一个函数,但它需要完全限定, 因为它用作运算符的参数<<(std::endl 是一个函数 指针,而不是函数调用)。
我的想法是评论不正确(或根本不清楚)。 我正在考虑将评论更改为说,而不是
请注意,std::endl 需要完全限定, 因为 ADL 不适用于函数调用的参数;它 仅适用于函数名称本身。
我是否正确,维基百科的评论不正确? 我提议的更改是否正确? (即,在这个例子中,我对ADL的理解是否正确?
维基百科所说的没有错。
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)
这显然需要对cout
和endl
进行命名空间限定,因为这是(函数的)依赖于参数的查找,而不是"参数查找"。
参数确定要调用的函数,而不是方法。
原始措辞和您的措辞都是正确的。
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 不适用。
维基百科条目是正确的。 operator<<
的操作数之一位于 std
命名空间中的事实导致名称查找包含来自命名空间std
的operator<<
声明,这些声明包含在设置为重载解析的候选声明中。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- std::vector::reserve(未知m),我知道m<<;N(通常)并且知道N
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- C++运算符<<调用::ostream而不是std::osttream
- 是std :: set&lt; std :: future&gt;不可能存在
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- BOOST ::变体无法解决运算符&lt;&lt;对于STD :: Ostream
- C++重载<<具有typedef'd std::vector
- 以x的倍数填充前导零,使用std::cout<<std::十六进制
- 错误:没有匹配'运算符<<"在'std::cout
- std::pair的默认构造函数<>将基本类型(int等)设置为零
- std::ostream&operator< & lt; (std:: ostream&压力,压力& &;val)
- 将std::endl传递给std::operator<<
- std::映射<>或std::vector<>在处理大型标志集时
- 重载& lt; & lt;使用命名空间std