匿名命名空间是否包含所有命名空间?

Jos*_*vin 7 c++ namespaces global anonymous linkage

在C++中,您可以通过将类和函数定义包装在匿名名称空间中来指定内部链接.您还可以显式实例化模板,但要符合模板的任何显式实例化的标准必须出现在同一名称空间中.AFAICT这应该编译,但GCC失败了:

namespace foo {

template<class T>
class bar {};

}

using namespace foo;

namespace {
template class bar<int>;
}

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有错误:

namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace 'foo')
Run Code Online (Sandbox Code Playgroud)

这很有趣,因为匿名命名空间应该只是指定链接,而不是真正作为命名空间运行,并且全局命名空间肯定包含foo,因为它包含每个命名空间.但即使这样也行不通!

template<class T>
class bar {};

using namespace foo;

namespace {
template class bar<int>;
}

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

哪个失败并出现相同的错误,只需列出全局命名空间:

namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace '::')
Run Code Online (Sandbox Code Playgroud)

:/

CB *_*ley 10

匿名命名空间在逻辑上等同于

namespace _TU_specific_unique_generated_name
{
    // ...
}
using namespace _TU_specific_unique_generated_name;
Run Code Online (Sandbox Code Playgroud)

名称空间(匿名或其他名称)对其成员的链接没有影响.特别是匿名命名空间的成员不会神奇地获得内部链接.


Mar*_*utz 7

第一:您是显式实例化类模板,而不是定义新的类模板.什么

template class bar<int>;
Run Code Online (Sandbox Code Playgroud)

说是"请在这里实例化类型int的类模板栏".您不能在另一个命名空间中执行此操作,就像您无法在另一个命名空间中部分地专门化类模板一样.特别是,必须已经定义了要显式实例化的模板,并且在您的示例中,没有(匿名命名空间):: bar <>,只有foo :: bar <>.

第二:匿名命名空间是一个真正的命名空间(尽管如此,它在每个翻译单元中都是不同的).它也没有神奇地改变联系.在namespace {}中声明的所有内容仍然具有默认链接,就像在任何其他命名空间范围内一样.IIRC,它甚至被添加到允许翻译单元 - 私有但外部链接对象.


Dre*_*ins 6

我认为你有答案 - 匿名命名空间是独特的,唯一的命名空间.顺便说一句,编译器生成一些随机大整数来在内部表示该命名空间.