模板别名范围

时间:2015-09-24 18:03:50

标签: c++ template-aliases

根据http://en.cppreference.com/w/cpp/language/type_alias,别名是块级声明。它没有说模板别名有什么特别之处,因此应该读取模板别名也是块级声明。

但是,在块级别上不可能使用模板别名。根据编译器的不同,错误是不同的 - 虽然g ++提供了一个有意义的消息,说在块范围内不允许模板,clang是完全神秘的。 (例如:http://coliru.stacked-crooked.com/a/0f0862dad6f3da61)。

到目前为止我遇到的问题:

  • cppreference是否无法指定模板别名不能在块范围内使用? (或者我需要参加阅读课程吗?)
  • 编译器是否正确拒绝块级别的模板别名(我觉得这个特性对我的特定编码习惯非常有意义)
  • 如果第二个答案是肯定的,那么这可能是什么理由?为什么编译器会否认我这种纯语法糖?

2 个答案:

答案 0 :(得分:6)

别名模板是[temp.alias]

  

声明是别名声明(第7条)的模板声明声明了标识符   是一个别名模板。别名模板是一系列类型的名称。别名模板的名称是a   模板名称。

如果我们看看14.2 [temp],我们有

  

模板声明只能作为命名空间范围或类范围声明出现。在一个功能   模板声明,declarator-id的最后一个组件不应该是template-id。

所以是的,cppreference说它可以在块范围内声明并且你的编译器是正确的。如果你点击了block declarations的链接,它将会显示一个声明列表,并且它已经Template declaration并且在那里它有

  

类的声明(包括struct和union),成员类或成员枚举类型,函数或成员函数,命名空间范围内的静态数据成员,类范围内的变量或静态数据成员,(自C + +14)或别名模板(自C ++ 11以来)它还可以定义模板特化。

至于为什么标准说模板只能在命名空间范围或类范围内声明我喜欢James Kanze answer

  

问题可能与实现模板的历史方式有关:早期实现技术(以及今天仍在使用的一些技术)要求模板中的所有符号都具有外部链接。 (实例化是通过在单独的文件中生成等效代码来完成的。)函数内定义的名称永远不会有链接,也不能在定义它们的范围之外引用。

答案 1 :(得分:1)

编译器表现正常。

C ++ 14标准的第14节:

  

模板声明只能作为命名空间范围或类出现   范围声明。