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
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: