【问题标题】:Does the anonymous namespace enclose all namespaces?匿名命名空间是否包含所有命名空间?
【发布时间】:2009-07-10 21:11:36
【问题描述】:

在 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 '::')

:/

【问题讨论】:

  • 哪个版本的 GCC - 或者哪个编译器选项 - 或者哪个平台?我在带有和不带有 -Wall 的 MacOS X 上使用 G++ 4.0.1 尝试了第一个示例,它编译时没有抱怨或警告。

标签: c++ namespaces global anonymous linkage


【解决方案1】:

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

namespace _TU_specific_unique_generated_name
{
    // ...
}
using namespace _TU_specific_unique_generated_name;

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

【讨论】:

  • 我要补充一点,那就是_TU_specific_unique_generated_name中的东西不能在文件之外使用。
  • 标准中实际上是这样描述的,接受。
【解决方案2】:

首先:您正在显式实例化一个类模板,而不是定义一个新的类模板。什么

template class bar<int>;

说是“请在此处实例化类型 int 的类模板栏”。你不能在另一个命名空间中这样做,就像你不能在另一个命名空间中部分专门化一个类模板一样。特别是,要显式实例化的模板必须已经定义,并且在您的示例中,没有(匿名命名空间)::bar,只有 foo::bar。

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

【讨论】:

    【解决方案3】:

    我想你有你的答案 - 匿名命名空间是不同的、独特的命名空间。顺便说一句,编译器会生成一些随机的大整数来在内部表示该命名空间。

    【讨论】:

      【解决方案4】:

      根据 Stroustrup(第 8.2.5.1 节),全局命名空间可以访问匿名(未命名)命名空间,但它没有明确表示相反。

      我希望您必须使用 using 语句指定命名空间或完全限定对未命名命名空间内其他命名空间的引用...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多