为什么名称查找在找到使用 directive 隐式声明的实体时不会停止?

Why does the name lookup does not stop when it finds the entity implicitly declared by using directive?

提问人:choxsword 提问时间:3/16/2018 最后编辑:Communitychoxsword 更新时间:3/16/2018 访问量:62

问:

代码示例如下:

#include<iostream>
using namespace std;
namespace B
{
  int ohoh=2;
}

namespace A
{
  int ohoh=666;
  namespace C 
  {
      //using B::ohoh;(as if declared by using directive) //why does the lookup not stops here?
      int foo()
      {
        using namespace B;
        cout<<ohoh<<endl;
      }
  }
}

int main()
{
    A::C::foo();
}  

输出为 666,但不是 2。为什么?

引自 cppref

对于非限定名称,即不出现在作用域解析运算符 :: 右侧的名称,名称查找将检查作用域,如下所述,直到找到至少一个任何类型的声明,此时查找停止,不再检查其他作用域。 (注意:从某些上下文中查找会跳过某些声明, 例如,查找 :: 左侧使用的名称会忽略函数、变量和枚举器声明,查找用作基类说明符的名称会忽略所有非类型声明)

出于非限定名称查找的目的,来自 using 指令指定的命名空间的所有声明都显示为在最近的封闭命名空间中声明,该命名空间直接或间接包含 using 指令和指定的命名空间。

从上面引用的段落来看,名称查找应该停在最近的,我在代码中注释的地方。为什么它不停下来找到?namespace CA::ohoh

顺便说一句,我认为我应该尽可能少地使用使用指令。

C++ using-directives 名称查找

评论


答:

6赞 Miles Budnek 3/16/2018 #1

出于非限定名称查找的目的,来自由 using 指令指定的命名空间的所有声明,就像在最近的封闭命名空间中声明一样,该命名空间包含 [...] using 指令和指定的命名空间

在本例中,包含两者和 using 指令的最近命名空间是全局命名空间。因此,所有名称都显示在内部,就好像它们是在全局命名空间中声明的一样。搜索 name 时,在全局命名空间之前搜索,找到第一个声明也是如此,名称查找就此停止。BBA::C::fooohohAA::ohoh

评论

0赞 Passer By 3/16/2018
他评论的声明实际上是一个使用声明
0赞 choxsword 3/16/2018
我明白了,我曾经认为最近的命名空间是C
0赞 Miles Budnek 3/16/2018
@PasserBy 从这个问题来看,在我看来,这只是为了说明。这就是 OP 认为应该注入这个名字的地方。不过,我可能误解了这个问题。
0赞 choxsword 3/16/2018
@PasserBy我只是把那个注释放在我的理解中显示最接近的命名空间。
0赞 choxsword 3/16/2018
@PasserBy 从我所引用的内容来看,我认为“好像声明”与声明具有相同的效果。using declaration