为什么两个不同的未命名命名空间可以共存于一个cpp文件中?

时间:2018-11-04 16:03:19

标签: c++ namespaces

据说翻译单位中只有一个唯一的未命名名称。但是,下面的行仍然可以编译。

//test.cpp
namespace xxx{
namespace {
int x = 0;
}
}
namespace yyy{
namespace {
int x = 0;
}
}

我猜测嵌套的未命名名称空间中的代码就像父命名空间中的代码一样,嵌套的未命名名称空间没有任何意义。不知道对不对。

2 个答案:

答案 0 :(得分:1)

未命名的名称空间对其作用域是唯一的。例如

namespace named {
namespace {
int x = 0;
}
namespace {
int x = 0;
}
}

将导致错误。全局范围也是如此。

对于您提供的情况,xxxyyy中的未命名名称空间对于它们各自的作用域是唯一的,因此不会发生名称冲突。

答案 1 :(得分:1)

匿名命名空间的规则与您期望的不同。
根据C ++标准/ [namespace.unnamed]:

  

未命名空间定义的行为就像被替换

inline namespace unique { /* empty body */ } 
using namespace unique ;
namespace unique { namespace-body }
     

当且仅当inline出现在   unnamed-namespace-definition和 unique 在   翻译单元 相同的标识符 所代替,   标识符不同于翻译单元中的所有其他标识符。

因此,您的代码是有效的,因为您每次都在不同封闭名称空间的嵌套匿名名称空间中定义x(如果uuuu是标准中提到的假设唯一标识符,它应该是xxx::uuuuyyy::uuuu)。

重要说明:每个匿名名称空间的行为就像它们具有相同的标识符(每个编译单元唯一)一样,允许继续嵌套嵌套的名称空间:

namespace xxx {
    namespace {
        int x = 20;
    }
}
namespace test {
    int x=30;     // no problem: it's a different namespace
}
namespace xxx {
    namespace {
        // int x;     --> forbiden because it's the same nested anonyous space than above  
        int y = x;    // refers to the already defined xxx::{anonymous}::x
    }
}
int main() {
    cout << xxx::y<<endl;    // output is 20 and xxx::y is inaccessible from other compilation units
    return 0;
}