为什么我必须写,std::cout而不是std::<<像这样的代码行:
#include <iostream>
int main() {
std::cout << "Hello, world!";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
cout来自std库,<<通常不习惯进行位移?那么,为什么我::之前也不必编写范围运算符<<,因为它也用于其他含义?编译器如何知道后std::cout,<<意味着另一件事?
dyp*_*dyp 55
首先,编译器将查看左侧和右侧的类型<<.std::cout是类型std::ostream,字符串文字是数组15const char的类型.由于左边是类类型,它将搜索名为的函数operator<<.问题是,它看起来会在哪里?
查找此名称operator<<是一种所谓的非限定查找,因为函数名称不合格std::operator<<.函数名称的非限定查找会调用依赖于参数的查找.依赖于参数的查找将搜索与参数类型相关联的类和名称空间.
当您包括时<iostream>,签名的自由功能
template<typename traits>
std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>&,
const char*);
Run Code Online (Sandbox Code Playgroud)
已在命名空间中声明std.此命名空间与类型相关联std::cout,因此将找到此函数.
std::ostream只是一个typedef std::basic_ostream<char, std::char_traits<char>>,15const char的数组可以隐式转换为a char const*(指向数组的第一个元素).因此,可以使用两种参数类型调用此函数.
还有其他的重载operator<<,但我上面提到的函数是参数类型和本例中选择的函数的最佳匹配.
参数依赖查找的一个简单示例:
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
}
Run Code Online (Sandbox Code Playgroud)
注意:由于此函数是运算符,因此实际查找有点复杂.它通过第一个参数范围内的限定查找(如果是类类型)查找,即作为成员函数.此外,执行非限定查找,但忽略所有成员函数.结果略有不同,因为不合格的查找实际上就像一个两步过程,其中依赖于参数的查找是第二步.如果第一步找到成员函数,则不执行第二步,即不使用依赖于参数的查找.
相比:
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
}
}
Run Code Online (Sandbox Code Playgroud)
至:
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
}
}
Run Code Online (Sandbox Code Playgroud)
在 std::cout << "Hello, world!"; //calls std:::operator <<
这是通过依赖于参数的名称查找(ADL,又名Koenig Lookup)实现的
虽然我们只有一个std限定符,但std命名空间有两个东西
cout<<没有ADL,(Koenig Lookup)
std::cout std:: << "Hello World" ;//this won't compile
为了编译它,我们需要使用它更加丑陋的形式
std::operator<<(std::cout, "Hello, world!");
所以为了避免这种丑陋的语法,我们必须欣赏Koenig Lookup :)
| 归档时间: |
|
| 查看次数: |
2234 次 |
| 最近记录: |