模板别名范围

Ser*_*eyA 3 c++ template-aliases

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

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

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

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

Nat*_*ica 6

别名模板是[temp.alias]

声明是别名声明(第7章)的模板声明声明标识符是别名模板.别名模板是一系列类型的名称.别名模板的名称是模板名称.

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

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

所以是的,cppreference说它可以在块范围内声明并且你的编译器是正确的.如果你点击块声明的链接它会带你到一个声明列表,并且它有模板声明,并且在那里它有

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

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

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