Assume the following code:
#include <iostream>
using namespace std;
namespace X
{
class A{};
void f(A a){}
void g(int a){}
}
int main()
{
X::A a;
f(a);
g(5);
}
When I compile the code, the following compile error occurs:
main.cpp: In function 'int main()':
main.cpp: error: 'g' was not declared in this scope
So the function f
is compiled perfectly, but g
isn't. How? Both of them belong to the same namespace. Does the compiler deduce that function f
belongs to the X
namespace from the argument of type X::A
? How does compiler behave in such cases?
This works for the function call expression:
because the namespace that
X::A
belongs to is included in the lookup for the functionf
due to argument dependent lookup(ADL), cppreference explains ADL as follows:This is covered in the draft C++ standard section
3.4.2
Argument-dependent name lookup:and goes on to say:
and includes the following bullet:
and further down provides a similar example to your problem:
The function call expression:
does not work because ADL does not add any namespaces for arguments that are fundamental types.
Herb Sutter covers ADL in Gotw #30 and in What's In a Class? - The Interface Principle.
works because of Argument-Dependent Lookup (Also known as Koenig Lookup).
a
is an object of classA
inside namespaceX
, when compiler searches a match-able functionf
, it will look into namespaceX
in this case. See Argument Dependent Lookup for more information.When the code
f(a)
, the compiler finds the functionvoid f(A a){}
in thenamespace X
because of the ADL (argument dependent lookup, also known as Koenig lookup).A
is declared in the namespaceX
, hence when the compiler needs to look up the definition off
, it includes possibilities from that namespace because the objecta
of typeA
is in that namespace (as declaredX::A a;
).On the other hand,
int
is not declared in thenamespace X
, so thenamespace X
is not included in the lookup. Since no corresponding function forf
is found, it fails to compile.