内部类型作为模板参数

Joh*_*ohn 6 c++ templates

ISO 98/03标准(第14.3.1节)似乎禁止使用具有内部链接的类型作为模板参数.(参见下面的示例.)C++ 11标准没有.G ++ - 使用旧标准 - 允许它.我误读了03标准,还是g ++只是让这个幻灯片?

namespace
{
    struct hidden { };
}

template<typename T>
struct S
{
   T t;
};

int main()
{
    S<hidden> s;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 7

你是正确的,C++ 03不允许使用具有内部链接的类型作为模板类型参数,而C++ 11则允许.

然而,我似乎记得,匿名命名空间内的定义仍然具有外部链接.


是的,3.5节[basic.link]

具有命名空间作用域(3.3.5)的名称具有内部链接(如果它的名称)

  • 显式声明为static的对象,引用,函数或函数模板,
  • 显式声明的对象或引用,const既未显式声明extern也未声明为具有外部链接; 要么
  • 匿名联盟的数据成员.

具有命名空间范围的名称具有外部链接(如果它的名称)

  • 一个对象或参考,除非它有内部联系; 要么
  • 一个功能,除非它有内部联系; 要么
  • 命名类(第9节),或在typedef声明中定义的未命名类,其中类具有用于链接目的的typedef名称(7.1.3); 要么
  • 命名枚举(7.2),或在typedef声明中定义的未命名枚举,其中枚举具有用于链接目的的typedef名称(7.1.3); 要么
  • 属于具有外部链接的枚举的枚举器; 要么
  • 模板,除非它是具有内部链接的功能模板(第14条); 要么
  • 命名空间(7.3),除非它在未命名的命名空间中声明.

您在命名空间范围内有一个命名类,它具有外部链接.

ISO/IEC 14882:2003第115页底部的脚注阐明:

虽然未命名的命名空间中的实体可能具有外部链接,但它们实际上由其翻译单元唯一的名称限定,因此永远不会从任何其他翻译单元中看到.

如果您有其他版本,请尝试查看第7.3.1.1节 [namespace.unnamed]