问题
I was looking at the Wikipedia entry on argument-dependent lookup, and (on Jan 04, 2014) the following example was given:
#include<iostream>
int main()
{
std::cout << "Hello World, where did operator<<() come from?" << std::endl;
}
... with the following comment:
Note that std::endl is a function but it needs full qualification, since it is used as an argument to operator<< (std::endl is a function pointer, not a function call).
My thought is that the comment is incorrect (or simply unclear). I am considering changing the comment to say, instead
Note that std::endl needs full qualification, because ADL does not apply to the arguments of a function call; it only applies to the function name itself.
Am I correct that the Wikipedia comment is incorrect? Is my proposed change correct? (I.e., is my understanding of ADL correct in this example?)
回答1:
There's nothing wrong about what Wikipedia says.
std::cout << "Hello World, where did operator<<() come from?" << std::endl
is equivalent to the following (assuming operator<<
is implemented as a free function)
operator<<(
operator<<(std::cout, "Hello World, where did operator<<() come from?"),
std::endl)
which clearly requires namespace qualification for both cout
and endl
because this is argument-dependent lookup (of the function), not "argument lookup".
The arguments determine the function to be called, not the way around.
回答2:
Both the original phrasing and your phrasing are correct.
std::endl
is a function. C++03 spec section 27.6 [lib.iostream.format]:
Header
<ostream>
synopsis
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);
...
In this context, the std::endl
function (or more precisely, the function pointer into which it decays) is being passed as an argument to operator<<
. Since it is an argument, ADL does not apply.
回答3:
The Wikipedia entry is correct. The fact that one of operator<<
's operands is in the std
namespace causes name lookup to include declarations of operator<<
from namespace std
in the candidate-declarations set fed to overload resolution.
来源:https://stackoverflow.com/questions/20926217/why-does-stdendl-require-the-namespace-qualification-when-used-in-the-statem