首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内部命名空间名称与全局命名空间名称匹配时的歧义

内部命名空间名称与全局命名空间名称匹配时的歧义
EN

Stack Overflow用户
提问于 2016-02-19 17:32:41
回答 3查看 258关注 0票数 1

语言律师,注意!

我有以下代码:

代码语言:javascript
复制
namespace conflicting 
{
    struct Foo {};
}

namespace outer
{
    namespace conflicting
    {
        struct Bar {};
    }
}

using namespace outer;

int main()
{
    conflicting::Bar b;
    return 0;
} 

使用g++ 4.8.2,在试图编译时会出现以下错误:

代码语言:javascript
复制
t.cpp: In function ‘int main()’:
t.cpp:18:5: error: reference to ‘conflicting’ is ambiguous
     conflicting::Bar b;
     ^
t.cpp:2:1: note: candidates are: namespace conflicting { }
 {
 ^
t.cpp:9:5: note:                 namespace outer::conflicting { }
     {
     ^
t.cpp:18:5: error: reference to ‘conflicting’ is ambiguous
     conflicting::Bar b;
     ^
t.cpp:2:1: note: candidates are: namespace conflicting { }
 {
 ^
t.cpp:9:5: note:                 namespace outer::conflicting { }
     {
     ^
t.cpp:18:22: error: expected ‘;’ before ‘b’
     conflicting::Bar b;

有人能向我解释一下为什么会发生这个错误吗(也许可以参考标准的一个部分)?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-19 17:41:10

快速总结:对于X::m是一个限定-id,X需要唯一地引用单个名称空间。

conflicting::Bar是一个限定id,如果conflicting是“一个命名空间的嵌套名称说明符”,而Bar是“该名称空间的一个成员的名称(或者使用-指令可以看到的名称空间成员的名称)”(所有引用都是对N3337的引用,所有的强调都是我的):

5.1.1一般expr.prim.general

  1. A ::,或一个命名名称空间 (7.3)的嵌套名称说明符,在这两种情况下,该名称空间成员的t名称(或使用指令可见的名称空间成员的名称)是一个限定-id;3.4.3.2描述了对出现在限定-id中的命名空间成员的名称查找。结果就是会员。结果的类型是成员的类型。如果成员是函数或变量,则结果为lvalue,否则为prvalue。

第3.4节描述了名称查找的过程,它要求名称查找为名称找到一个明确的声明(重载函数是例外):

3.4Name查找basic.lookup

  1. 在语法允许特定规则讨论的上下文中,名称查找规则一致地适用于所有名称(包括ty胡枝子名称(7.1.3)、命名空间名称(7.3)和类名(9.1))。名称查找将名称的使用与该名称的声明(3.1)相关联。名称查找应该为名称找到一个明确的声明(参见10.2)。如果名称查找发现名称是函数名,则它可以将多个声明与名称关联起来;声明被称为形成一组重载函数(13.1)。重载解析(13.3)发生在名称查找成功之后。访问规则(第11条)仅在名称查找和函数重载解析(如果适用的话)成功后才被考虑。只有在名称查找、函数重载解析(如果适用的话)和访问检查成功之后,才会在表达式处理中进一步使用名称的声明引入的属性(第5条)。

第3.4.3.2节的措辞明确指出名称空间必须是唯一的:

3.4.3.2名称空间成员namespace.qual

  1. 对于名称空间X和名称m,命名空间限定查找集S(X,m)定义如下:设S'(X,m)是X中m的所有声明集,内联命名空间集X (7.3.1)。如果S'(X,m)不是空的,则S(X,m)是S'(X,m);否则,S(X,m)是用X中的-指令及其内联命名空间集命名的所有命名空间Ni的S(X,m)的并。

这种描述假定X是唯一的,因为它没有描述迭代一组可能的名称空间来查找m的任何过程。

由于编译器无法确定要使用哪个conflicting命名空间作为命名空间成员查找的起点,因此会给出一个错误。

希望这能有所帮助。

票数 0
EN

Stack Overflow用户

发布于 2016-02-19 17:35:51

您用conflicting::限定了一个名称,所以编译器需要在该范围内查找Bar .但是哪个范围呢?它可以引用两种不同的方法,即::conflictingouter::conflicting,因为使用-指令可以不用outer::前缀来引用它们。

票数 1
EN

Stack Overflow用户

发布于 2016-02-19 17:34:52

哟,这不需要语言律师!一旦将outer命名空间引入当前的名称空间(通过using ),它的所有名称都变得可见。所以现在你们有冲突了。

这就是为什么我强烈地讨论using (命名空间)的实践。名称空间的出现是有原因的,其原因是为了防止此类问题的发生。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35511323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档