提问人:Anirban Sarkar 提问时间:4/27/2019 最后编辑:SwordfishAnirban Sarkar 更新时间:4/27/2019 访问量:736
为什么不能直接定义匿名 struct/class-es 的模板化别名?
Why can templated aliases of anonymous struct/class-es not be defined directly?
问:
我可以创建以下内容:
using Foo = struct { /*Implementation*/ };
template<class>
using Bar = Foo;
但是,不允许出现以下情况:
template<class>
using Bar = struct { /*Implementation*/ };
Clang 的错误比 GCC 更有用,并指出:
错误:“(File:Line:Column)的匿名结构”无法定义 在类型别名模板中
不允许使用第二个代码示例的任何原因?
注意:
请说明第二个代码示例(如果允许)可能导致语言问题的任何示例。
该标准的任何引用也会有所帮助。
答:
7赞
dfrib
4/27/2019
#1
[dcl.typedef]/2 禁止在作为模板别名一部分的别名声明中定义类或枚举:
typedef-name 也可以由 alias-declaration 引入。
...
如果 alias-declaration 是 模板声明。
后者是在CWG第1159期被接受时引入的,作为FCD N3092的一部分。
相关 N3092 评论 US 74 的评论和拟议解决方案确实提供了一些理由来解释为什么引入此限制 [强调我的]:
评论 (ID) 美国 74
评论
别名声明允许定义类或枚举类型 在其类型 ID (7.1.6p3) 中。但是,目前尚不清楚这是否是 当 alias-declaration 是模板别名的一部分时,这是可取的:
template<typename T> using A = struct { void f(T) { } };
决议案
要么禁止在 模板别名,或禁止在此类别名中使用模板参数 定义,或添加一个示例来说明此用法。
所有者 & 问题
配置
接受
现在禁止在模板别名中定义类或枚举。
似乎没有人抗议(足够令人信服)禁止在模板别名中定义类和枚举,这意味着很可能没有人能够给出一个令人信服的例子来说明这在哪些方面是有用的。
评论
0赞
koe
3/30/2022
模板别名不能专用化,因此在别名中定义的类是不可专用的。这将允许您定义一个不能重载的模板函子(这可能会使模板更加安全,因为它可以防止依赖项的恶意重载注入)。
评论
struct Foo
struct Bar
using Bar1 = struct Foo1 { /*Implementation*/ };
template<class> using Bar2 = struct Foo2 { /*Implementation*/ };
error: types may not be defined in alias template declarations