namespace A
{
int overloaded_f(float some_float);
enum class Enum { Value };
}
namespace B
{
int overloaded_f(A::Enum some_enum);
int f(A::Enum some_enum){
using A::overloaded_f;
// using B::overloaded_f;
// return B::overloaded_f(some_enum) + overloaded_f(0.0f);
return overloaded_f(some_enum) + overloaded_f(0.0f);
/* error: cannot convert 'A::Enum' to 'float'
14 | return overloaded_f(some_enum) + overloaded_f(0.0f);
| ^~~~~~~~~
| |
| A::Enum
*/
}
}
int main(){
A::Enum a = A::Enum::Value;
return B::f(a);
}
Uncommenting the (//
) code lines would remove the error.
From basic.lookup.unqual:
§6.4.1 Unqualified name lookup [basic.lookup.unqual]
- In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
- The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see [namespace.udir]. For the purpose of the unqualified name lookup rules described in [basic.lookup.unqual], the declarations from the namespace nominated by the using-directive are considered members of that enclosing namespace.
Does the code snippet fail to compile because name lookup ends as soon as a declaration is found for the name
?
Does the code snippet fail to compile because name lookup ends as soon as a declaration is found for the name?
You're correct. The lookup of overloaded_f
in the expression overloaded_f(some_enum)
has two components:
using A::overloaded_f
.A
(the namespace in which the enum type is declared). It does not find anything that is inside namespace B
.