I thought that in a nested namespace, anything that is part of the parent (or global) namespace is considered equally for overload resolution, but this example seems to show otherwise.
This works fine:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
void foo(float) { std::cout << "float\n"; }
namespace NS {
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}
The call to foo(0)
matches foo(int)
since it is a better match and everything works as expected. However, if I move the declaration of foo(float)
into the namespace:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
namespace NS {
void foo(float) { std::cout << "float\n"; }
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}
The call to foo(0)
now calls foo(float)
!
I have searched through https://en.cppreference.com/w/cpp/language/overload_resolution and many other such pages to find the rule that explains this, but I seem to be missing it. Can someone please explain which of the many complex overload resolution rules causes this, or is it something else?
EDIT
I just discovered it is even weirder. Even if the foo
inside the namespace doesn't match at all, it still won't use the one outside. This just completely fails to compile:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
namespace NS {
void foo(float, float) { std::cout << "float\n"; }
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}