在我最近编写的代码中,我注意到了一种奇怪的行为。
[当我使用make_pair
且第一个参数为std::pair
时,make_pair
在名称空间中变得“神奇”可用(我不必使用std::
限定符)
#include <iostream>
int main()
{
int i1 = 2; int i2 = 10; int i3 = 0;
// constructing a pair using std::make_pair, everything's okay
std::pair<int,int> key = std::make_pair(i1, i2);
// here, why is make_pair suddenly magically available without the
// std:: namespace qualifier?
// At the same time, using ::make_pair yields and error
// (make_pair has not declared...)
std::pair<std::pair<int,int>, int> mypair = make_pair(key, i3);
std::cout << mypair.first.first << "\n";
std::cout << mypair.first.second << "\n";
std::cout << mypair.second << "\n";
return 0;
}
编译正常(使用-Wall and -pedantic-errors
并输出:
2
10
0
为什么会这样?我调查了cppreference,但没有发现此行为正确的任何提示。我有什么遗漏吗?
仅供参考,我使用的是gcc 4.6.3
这是C ++的一个鲜为人知的功能,如@jrok指出的那样,速度很快,Koenig Lookup或现代C ++中的1),ADL(依赖于参数的查找)。它的作用基本上是在参数的命名空间中搜索您要调用的函数(在此示例中为make_pair
)。触发ADL的参数显然是std::pair
。
1] 名称已更改,尽管很多人都知道第一个术语
也许值得一提的是,ADL对于一种特定类型的功能非常重要:运算符。如果不是ADL,那么即使是琐碎的C ++“你好,世界!”也将是不可能的。工作,因为这:
std::cout << "Hello, world!";
必须这样写:
std::operator<< (std::cout, "Hello, world!");
感谢ADL,<<
已正确解析为位于std
名称空间中。
参考: