make_pair命名空间污染

时间:2013-06-25 09:15:47

标签: c++ gcc stl std-pair

在我最近写的代码中,我注意到了一种奇怪的行为。

当我使用make_pair时,第一个参数为std::pairmake_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

1 个答案:

答案 0 :(得分:22)

这是一个鲜为人知的C ++特性,因为@jrok指出速度极快,Koenig Lookup,或现代C ++ 1) ADL (参数依赖查找) )。它的作用基本上是在你想要调用的函数的参数的名称空间中搜索(在这个例子中是make_pair)。触发ADL的参数显然是std::pair

1) 命名已经改变,虽然很多人都知道第一个词


也许值得一提的是,ADL对于一种特定类型的功能非常重要:运营商。如果不是这样,即使是微不足道的C ++也不可能“你好,世界!”工作,因为:

std::cout << "Hello, world!";

必须写成:

std::operator<< (std::cout, "Hello, world!");

感谢ADL,<<已正确解析为std命名空间。


参考文献: