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

Why can templated aliases of anonymous struct/class-es not be defined directly?

提问人:Anirban Sarkar 提问时间:4/27/2019 最后编辑:SwordfishAnirban Sarkar 更新时间:4/27/2019 访问量:736

问:

我可以创建以下内容:

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

template<class>
using Bar = Foo;

但是,不允许出现以下情况:

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

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

错误:“(File:Line:Column)的匿名结构”无法定义 在类型别名模板中


不允许使用第二个代码示例的任何原因?

注意:

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

  • 该标准的任何引用也会有所帮助。

C++ C++11 模板 language-lawyer using-directives

评论

2赞 bolov 4/27/2019
我不知道你可以做第一个片段。
3赞 bolov 4/27/2019
你为什么要做这样的事情?为什么不呢?您在哪里以及为什么需要它?struct Foo
2赞 bolov 4/27/2019
我再问一遍:为什么不呢?你为什么想要匿名课程?另请注意,对于每个虚构实例化,基本模板定义上的静态断言是 UB。struct Bar
3赞 OznOg 4/27/2019
我想根本原因是你可以写,但不是你得到的,这是恕我直言的不一致using Bar1 = struct Foo1 { /*Implementation*/ };template<class> using Bar2 = struct Foo2 { /*Implementation*/ };error: types may not be defined in alias template declarations
3赞 super 4/27/2019
@AnirbanSarkar 当你声明一个用途时,你给它起了一个名字。这与一开始就给它起个名字没有什么不同。因此,我对你的动机感到困惑。如果要将某些内容包含在 c++ 标准中,则需要有人为它编写提案、实现它等。我认为,某些东西没有用的事实会导致这样一个事实,即没有人会经历做这项工作的麻烦,这是一个相当合理的解释。

答:

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) { } };

决议案

要么禁止在 模板别名,或禁止在此类别名中使用模板参数 定义,或添加一个示例来说明此用法

所有者 & 问题

CWG 1159系列

配置

接受

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

似乎没有人抗议(足够令人信服)禁止在模板别名中定义类和枚举,这意味着很可能没有人能够给出一个令人信服的例子来说明这在哪些方面是有用的。

评论

0赞 koe 3/30/2022
模板别名不能专用化,因此在别名中定义的类是不可专用的。这将允许您定义一个不能重载的模板函子(这可能会使模板更加安全,因为它可以防止依赖项的恶意重载注入)。