使用声明后,非限定名称查找不会在本地命名空间中查找

Unqualified name lookup does not look in local namespace after using declaration

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);
}

Link to Godbolt.

取消注释 (//) 代码行将消除错误。

来自basic.lookup.unqual

§6.4.1 Unqualified name lookup [basic.lookup.unqual]

  1. 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.
  2. 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.

代码片段编译失败是否因为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?

你是对的。在表达式 overloaded_f(some_enum) 中查找 overloaded_f 有两个组成部分:

  • 不合格的组件:一旦找到声明就停止向外搜索,在这种情况下意味着它停止在using A::overloaded_f
  • argument-dependent 组件:它只查看与其参数类型关联的名称空间内部。在这种情况下,关联的命名空间是 A(声明枚举类型的命名空间)。它找不到名称空间 B.
  • 内的任何内容