Let's have a look at the error message that GCC produces:
test.cpp: In function ‘void fun(NS1::Object, int)’:
test.cpp:19:48: error: call of overloaded ‘format(NS1::Object&)’ is ambiguous
void fun(Object b, int i) { int i1 = format(b); }
^
test.cpp:19:48: note: candidates are:
test.cpp:14:5: note: int NS3::format(const NS1::Object&)
int format(const Object&) { std::cout << "NS3"; }
^
test.cpp:5:5: note: int NS1::format(const NS1::Object&)
int format(const Object&) { std::cout << "NS1"; }
^
The ambiguity arises because of argument-dependent lookup:
Argument-dependent lookup, also known as ADL, or Koenig lookup, is the set of rules for looking up the unqualified function names in function-call expressions, including implicit function calls to overloaded operators. These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.
In your case, you are trying to call format(b)
where b
is a NS1::Object
.
- The function
int NS3::format(const NS1::Object&)
is considered because you pulled in that namespace.
- The function
int NS1::format(const NS1::Object&)
is considered because of ADL: The parameter is from namespace NS1
, so the matching function from NS1
will be considered as well.
- Both functions have the exact same signature and are hence ambiguous.
It's worth reading What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")? as well.