8

In the code I've been writing recently, I've noticed a strange behaviour.

When I use make_pair with the first argument being an std::pair, make_pair becomes "magically" available in the namespace (I don't have to use an std:: qualifier)

#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;
}

The compiles just fine (with -Wall and -pedantic-errors) and outputs:

2
10
0

Why is this happening? I've looked into cppreference and didn't find any hint of this behaviour being correct. Am I missing anything?

FYI, I'm using gcc 4.6.3

  • 8
    [Argument dependent (a.k.a. Koenig) lookup](http://en.wikipedia.org/wiki/Argument-dependent_name_lookup). Some useful SO links/possible dups: [1](http://stackoverflow.com/questions/4886478/functions-with-class-arguments-are-leaked-from-a-namespace/4886535#4886535), [2](http://stackoverflow.com/questions/4276772/why-was-argument-dependent-lookup-invented), [3](http://stackoverflow.com/questions/8111677/detailed-explanation-on-how-koenig-lookup-works-with-namespaces-and-why-its-a-go/8111750#8111750). โ€“ jrok Jun 25 '13 at 09:17
  • that was fast... thank you! โ€“  Jun 25 '13 at 09:24
  • You're welcome, well written question, btw. ADL is not without its problems, this is a good read: [What are the pitfalls of ADL?](http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl) โ€“ jrok Jun 25 '13 at 09:28

1 Answers1

22

That's a less-known feature of C++, as @jrok pointed out blazingly fast, Koenig Lookup, or in modern C++ 1), ADL (Argument-Dependent Lookup). What it does is basically searches in the namespaces of the arguments for the function that you want to call (make_pair in this example). The argument triggering the ADL is obviously std::pair.

1)the naming has been changed, though a lot of people know the first term


Perhaps it's worth mentioning that ADL is quite important for one particular type of function: operators. If not for ADL, it would be impossible for even the trivial C++ "hello, world!" to work, because this:

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

Would have to be written as this:

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

Thanks to ADL, << is properly resolved to be in std namespace.


References:

Joy
  • 321
  • 1
  • 9
Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135