问题描述
为什么我必须写
还有其他重载 operator<< ,但上面提到的函数是参数类型和在这种情况下选择的参数类型的最佳匹配。
A参数相关查找的简单示例:
命名空间my_namespace
{
struct X {};
void find_me(X){}
}
int main()
{
my_namespace :: X x;
find_me(x); //查找my_namespace :: find_me因为参数类型
}
注意由于此函数是运算符,因此实际查找有点复杂。它通过在第一个参数的范围内的合格查找(如果是类类型的)查找,即作为成员函数。 另外,执行无限制查找,但忽略所有成员函数。结果稍有不同,因为非限定查找实际上是一个两步过程,其中依赖于参数的查找是第二步。如果第一步找到成员函数,则不执行第二步,即不使用依赖于参数的查找
。比较: / p>
命名空间my_namespace
{
struct X
{
void find_me int){}
void search();
};
void find_me(X,double){}
void X :: search(){
find_me(* this,2.5); //仅查找X :: find_me(int)
//纯无限查找(第一步)查找成员函数
//不执行与参数相关的查找
}
}
至:
namespace my_namespace
{
struct X
{
void operator<<(int){}
void search
};
void operator<<(X,double){}
void X :: search(){
* this< 2.5; //找到它们,因为两个步骤总是执行
//并且重载解决方案选择自由函数
}
}
Why do I have to write std::cout and not also std::<< in a line of code like this:
#include <iostream> int main() { std::cout << "Hello, world!"; return 0; }
cout comes from std library, and isn't << usually used to do bits shifting? So, why don't I have to write the scope operator :: also before <<, since it is used also with another meaning? How the compiler knows that after std::cout, << means another thing?
First, the compiler will look at the types to the left and right of <<. std::cout is of type std::ostream, the string literal is of type array of 15 const char. As the left is of class type, it will search for a function named operator<<. The question is, where will it look?
The lookup for this name operator<< is a so-called unqualified lookup, because the function name isn't qualified like std::operator<<. Unqualified lookup for function names invokes argument-dependent lookup. The argument-dependent lookup will search in the classes and namespaces associated with the argument types.
When you include <iostream>, a free function of the signature
template<typename traits> std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>&, const char*);
has been declared in namespace std. This namespace is associated with the type of std::cout, therefore this function will be found.
std::ostream is just a typedef for std::basic_ostream<char, std::char_traits<char>>, and the array of 15 const char can be converted implicitly to a char const* (pointing to the first element of the array). Therefore, this function can be called with the two argument types.
There are other overloads of operator<<, but the function I mentioned above is the best match for the argument types and the one selected in this case.
A simple example of argument-dependent lookup:
namespace my_namespace { struct X {}; void find_me(X) {} } int main() { my_namespace::X x; find_me(x); // finds my_namespace::find_me because of the argument type }
N.B. As this function is a operator, the actual lookup is a bit more complex. It is looked up via qualified lookup in the scope of the first argument (if that's of class type), i.e. as a member function. Additionally, unqualified lookup is performed, but ignoring all member functions. The result is slightly different, because unqualified lookup is actually like a two-step procedure, where argument-dependent lookup is the second step. If the first step finds a member function, the second step is not performed, i.e. argument-dependent lookup is not used.
Compare:
namespace my_namespace { struct X { void find_me(X, int) {} void search(); }; void find_me(X, double) {} void X::search() { find_me(*this, 2.5); // only finds X::find_me(int) // pure unqualified lookup (1st step) finds the member function // argument-dependent lookup is not performed } }
to:
namespace my_namespace { struct X { void operator<<(int) {} void search(); }; void operator<<(X, double) {} void X::search() { *this << 2.5; // find both because both steps are always performed // and overload resolution selects the free function } }
这篇关于为什么我必须写std :: cout,而不是std ::<<的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!