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)
名称空间(匿名或其他名称)对其成员的链接没有影响.特别是匿名命名空间的成员不会神奇地获得内部链接.
第一:您是显式实例化类模板,而不是定义新的类模板.什么
template class bar<int>;
Run Code Online (Sandbox Code Playgroud)
说是"请在这里实例化类型int的类模板栏".您不能在另一个命名空间中执行此操作,就像您无法在另一个命名空间中部分地专门化类模板一样.特别是,必须已经定义了要显式实例化的模板,并且在您的示例中,没有(匿名命名空间):: bar <>,只有foo :: bar <>.
第二:匿名命名空间是一个真正的命名空间(尽管如此,它在每个翻译单元中都是不同的).它也没有神奇地改变联系.在namespace {}中声明的所有内容仍然具有默认链接,就像在任何其他命名空间范围内一样.IIRC,它甚至被添加到允许翻译单元 - 私有但外部链接对象.