Take following code as an example
#include <algorithm>
namespace baz {
template<class T>
void sort(T&&){}
}
namespace boot {
const auto sort = [](auto &&){};
}
void foo (){
using namespace std;
using namespace baz;
sort(1);
}
void bar(){
using namespace std;
using namespace boot;
sort(1);
}
I expected that since foo
compiled, then bar
shall compile as well. To my surprise, the foo
compiles correctly and bar
has problem with ambiguous call to sort
function. Am I doing something illegal here or this is proper way compiler should behave? If so, why is it so different. I though generic lambda can be treated as syntactic sugar for generic function.
live example
The problem here is not that the call to sort
is ambiguous, but that the name sort
is ambiguous. Name lookup happens before overload resolution.
I believe the relevant section is [basic.lookup]/1, specifically
[…] The declarations found by name lookup shall either all denote the same entity or shall all denote functions or function templates; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]). […]
In your case, the name sort
denotes both, the object boot::sort
as well as the set of overloaded functions std::sort
. Therefore, name lookup fails.
Your code is really no different from if you had written, for example
namespace baz {
int a;
}
namespace boot {
int a;
}
void foo() {
using namespace baz;
using namespace boot;
a = 42; // error: reference to 'a' is ambiguous
}
Try it out here; compare this to a case that actually has an ambiguous function call; note how the error message is the same as in your case, specifically referring to the name itself being ambiguous rather than the function call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With