为什么不能直接定义匿名struct / class-es的模板别名?

时间:2019-04-27 07:14:05

标签: c++ c++11 templates language-lawyer using-directives

我可以创建以下内容:

using Foo = struct { /*Implementation*/ };

template<class>
using Bar = Foo;

但是不允许以下情况:

template<class>
using Bar = struct { /*Implementation*/ };

来自Clang的错误比GCC更有用,并指出:

  

错误:“( file:line:column 处的匿名结构)无法定义”   在类型别名模板中


为什么不允许第二个代码示例?

注意:

  • 请说明第二个代码示例(如果允许)可能导致语言问题的所有示例。

  • 从标准中引用任何内容也是有帮助的。

1 个答案:

答案 0 :(得分:7)

alias-declaration禁止在[dcl.typedef]/2中定义属于模板别名的类或枚举:

  

一个typedef-name   也可以由   alias-declaration

     

...

     

  defining-type-specifier-seq   的   defining-type-id   如果以下情况不能定义类或枚举:   alias-declaration   是的declaration   一种   template-declaration

后者被引入是因为CWG issue 1159被接受为FCD N3092的一部分。

相关N3092 comment US 74的评论和建议的解决方案确实为为什么引入此限制提供了一些理由[ 强调 我的]:

  

评论(ID)US 74

     

评论

     

别名声明允许定义类或枚举类型   在其类型ID(7.1.6p3)中。但是,目前尚不清楚   如果别名声明是模板别名的一部分,则可取:

template<typename T> using A =
struct { void f(T) { } };
     

建议的分辨率

     

禁止在其中定义类和枚举   模板别名 ,或禁止在此类模板中使用模板参数   定义, 或添加示例以说明这种用法

     

所有者和问题

     

CWG 1159

     

处置

     

接受

     

现在在模板别名中禁止定义类或枚举。

似乎没有人抗议(令人信服地)禁止在模板别名中定义类和枚举,这暗示着没有人能够给出一个令人信服的示例来说明在何处有用。