在C++中,您可以通过将类和函数定义包装在匿名名称空间中来指定内部链接。您也可以显式实例化模板,但为了符合标准,模板的任何显式实例化都必须出现在同一命名空间中。AFAICT这是应该编译的,但GCC失败了:
namespace foo {
template<class T>
class bar {};
}
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}出现以下错误:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace 'foo')这很有趣,因为匿名名称空间应该只是指定链接,而不是真正起到名称空间的作用,而全局名称空间肯定包含foo,因为它包含每个名称空间。但即使这样也不起作用!:
template<class T>
class bar {};
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}这将失败,并返回相同的错误,只列出全局名称空间:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace '::'):/
发布于 2009-07-10 21:27:48
匿名命名空间在逻辑上等同于
namespace _TU_specific_unique_generated_name
{
// ...
}
using namespace _TU_specific_unique_generated_name;命名空间,无论是匿名的还是其他的,对其成员的链接都没有影响。具体地说,匿名命名空间的成员不会神奇地获得内部链接。
发布于 2009-07-10 21:26:56
首先:您正在显式实例化一个类模板,而不是定义一个新的类模板。什么
template class bar<int>;意思是“请在这里为int类型实例化类模板栏”。您不能在另一个名称空间中这样做,就像您不能在另一个名称空间中部分专门化一个类模板一样。特别是,必须定义要显式实例化的模板,并且在您的示例中,没有(匿名名称空间)::bar<>,只有foo::bar<>。
第二:匿名名称空间是一个真实的名称空间(尽管它在每个翻译单元中都是不同的)。它也不会神奇地改变链接。在命名空间*{}中声明的所有内容仍然具有默认链接,就像在任何其他命名空间作用域中一样。IIRC,它甚至被添加以允许翻译单元私有,但外部链接对象。
发布于 2009-07-10 21:18:40
我想你已经知道答案了--匿名名称空间是独特的、唯一的名称空间。顺便说一句,编译器在内部生成一些随机的大整数来表示该命名空间。
https://stackoverflow.com/questions/1112005
复制相似问题