C++ strange ambiguous call to overloaded function
ambiguous, c++, compiler-theory, namespaces
Solution
'void a(foo)' [found using argument-dependent lookup]
Well, surprisingly MSVC has a very good error explanation:
Following the standard, inside a function the compiler look for symbols in the current namespace and in the namespace where the type of the arguments are defined.
In the first case `a` is in `foobar` and in the namespace of the argument type `foo`: the global namespace, making it ambiguous.
In the second case `a` is in `foobar` but not in the namespace of the argument type `bar::foo`: with is `bar`.
Problem
First of all, this question is purely of theoretical nature. I am not searching for a solution (I already know it), I am just searching for an explanation. The following code doesn't compile: ``` struct foo {}; void a(foo) {} namespace foobar { void a(foo) {} void b(foo f) {a(f);} } int main() {return 1;} ``` MSVC++: ``` 1>c:\projects\codetests\main.cpp(7) : error C2668: 'foobar::a' : ambiguous call to overloaded function 1> c:\projects\codetests\main.cpp(4): could be 'void foobar::a(foo)' 1> c:\projects\codetests\main.cpp(2): or 'void a(foo)' [found using argument-dependent lookup] 1> while trying to match the argument list '(foo)' ``` G++: ``` main.cpp: In function 'void foobar::b(foo)': main.cpp:5:20: error: call of overloaded 'a(foo&)' is ambiguous main.cpp:5:20: note: candidates are: main.cpp:4:7: note: void foobar::a(foo) main.cpp:2:6: note: void a(foo) ``` While this code compiles (MSVC++ and G++): ``` namespace bar {struct foo {};} void a(bar::foo) {} namespace foobar { void a(bar::foo) {} void b(bar::foo f) {a(f);} } int main() {return 1;} ``` Why is that? What does the namespace around foo change for the compiler here? Is this behaviour defined in the C++-Standard? Is there any other explanation? Thanks.