8

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

当我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

4

1 回答 1

22

这是 C++ 的一个鲜为人知的特性,正如 @jrok 指出的极快的 Koenig Lookup,或者在现代 C++ 1)中,ADL(Argument-Dependent Lookup)。它所做的基本上是在参数的名称空间中搜索要调用的函数(make_pair在本例中)。触发 ADL 的论据显然是std::pair.

1)改名了,虽然很多人都知道第一个词


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

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

必须写成这样:

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

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


参考:

于 2013-06-25T09:17:50.150 回答