名称查找歧义不一致

Name-lookup ambiguity inconsistency

提问人:Supremum 提问时间:7/18/2015 更新时间:7/18/2015 访问量:108

问:

我试图理解为什么这个程序没有给 i 一个名称查找歧义:

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X;
    }

    using namespace P;

    int l = i;
}

int main() {}

如果我们这样修改它,我们会得到一个名称查找歧义:

namespace X { int i = 1; }

namespace P {        
    int i = 2;
    using namespace X;
}

using namespace P;

int l = i;

int main() {}

我在这里所做的唯一更改是删除命名空间 Q 并将其内容放在全局命名空间中。

我尝试了 3 种不同的编译器:

所有这些都给出了这封电子邮件中所述的结果,我正试图找出原因。

谁能用 c++ 标准来解释这种行为?我不明白。

C++ 语言律师 using-directives 名称查找

评论

2赞 dyp 7/18/2015
这不是刚刚在 std-discussion 上得到答案吗?groups.google.com/a/isocpp.org/d/msg/std-discussion/7K4p4FCdq6o/......
1赞 dyp 7/18/2015
仔细想想,这是一个关于 SO 的有效问题,但可能是重复的。
2赞 dyp 7/18/2015
相关/重复:stackoverflow.com/q/10741428

答:

1赞 Vlad from Moscow 7/18/2015 #1

在第一个程序中,used 变量在命名空间 P 中定义,因为 using 指令i

using namespace X;

将 X 的声明放在全局命名空间(X 和 P 的通用名称)中。因此,在 P 中的声明(更准确地说,由于另一个 using 指令,在 Q 中)隐藏了全局命名空间中的声明。iX::i

从 C++ 标准(3.4.1 非限定名称查找)

2 来自 using 指令指定的命名空间的声明 在包含 using 指令的命名空间中变得可见;看 7.3.4.

所以我们有第一个程序

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X; // 1
    }

    using namespace P; // 2

    int l = i;
}

使用指令 #1 的封闭命名空间是全局命名空间,使用指令 #2 的封闭命名空间是 namepsace Q。

在第二个程序中,由于这两个 using 指令,这两个定义都放在全局命名空间中i

//...
using namespace X;
//...
using namespace P;