3

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

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

到目前为止我的问题:

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

2 回答 2

6

别名模板是 [temp.alias]

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

如果我们看一下 14.2 [temp] 我们有

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

所以是的,cppreference 没有说它可以在块范围内声明并且你的编译器是正确的。如果您确实单击块声明的链接,它将带您进入声明列表,并且它有模板声明,并且在那里它有

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

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

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

于 2015-09-24T18:15:33.760 回答
1

编译器的行为正确。

C++14 标准的第 14 节:

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

于 2015-09-24T18:15:15.473 回答