类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗 [英] Can class template constructors have a redundant template parameter list in c++20
问题描述
据我所知,以下代码:
template<typename T>
struct S {
S<T>();
};
格式正确,即使< T>
但是,在gcc主干(而不是gcc10.2上)上,使用 -std = c ++ 20
,这会产生错误:
However, on gcc trunk (but not on gcc10.2), with -std=c++20
this gives an error:
error: expected unqualified-id before ')' token
3 | S<T>();
^
代码使用 -std = c ++ 20
在clang干线上编译。这是bug,还是c ++ 20中尚未在所有编译器中实现的重大更改?
The code compiles on clang trunk with -std=c++20
. Is this a bug, or is this a breaking change in c++20 that is yet to be implemented in all compilers?
推荐答案
实际上发生了变化。它记录在C ++ 20草案的兼容性部分。
There was a change, in fact. It's documented in the compatibility section of the C++20 draft.
[diff.cpp17.class]
2 受影响的子句:[class.ctor]和[class.dtor]
更改:一个简单模板ID不再作为声明者有效,构造函数或析构函数的ID。
理性:删除可能容易出错的冗余选项。
对原始功能的影响:有效的C ++ 2017代码可能无法在此国际标准中进行编译。例如:
2 Affected subclauses: [class.ctor] and [class.dtor]
Change: A simple-template-id is no longer valid as the declarator-id of a constructor or destructor.
Rationale: Remove potentially error-prone option for redundancy.
Effect on original feature: Valid C++ 2017 code may fail to compile in this International Standard. For example:
template<class T>
struct A {
A<T>(); // error: simple-template-id not allowed for constructor
A(int); // OK, injected-class-name used
~A<T>(); // error: simple-template-id not allowed for destructor
};
具体来说,字词变化量是这样的:
Specifically, the wording delta is this:
n4659 -C ++ 17标准草案- [class.ctor]
n4659 - C++17 standard draft - [class.ctor]
1 构造函数没有名称。在构造函数的声明中,
声明符是形式为函数的声明符
1 Constructors do not have names. In a declaration of a constructor, the declarator is a function declarator of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
其中ptr-declarator仅包含一个id表达式,一个可选属性- specifier-seq和可选的括号,并且id-expression具有以下形式之一:
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:
- 在属于成员的成员声明中,类的规范,但不是朋友声明,id-expression是立即封闭类的注入类名称;
- 在属于该成员的成员声明中-类模板的规范,但不是朋友声明,id表达式是
a类名,用于命名
立即封闭类模板的当前实例;或
n4861 -C ++ 20标准草案- [class.ctor]
n4861 - C++20 standard draft - [class.ctor]
1 构造函数由声明所引入,该声明的声明符是形式为
的函数声明符([dcl.fct])
1 A constructor is introduced by a declaration whose declarator is a function declarator ([dcl.fct]) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
其中ptr-declarator仅包含一个id表达式,
可选的attribute-specifier-seq和可选的
括号,并且id表达式具有以下形式之一:
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:
- 在属于类或类模板的成员规范但不是朋友声明
([class.friend])的成员声明中,id表达式是注入的类名$紧邻的实体的b $ b([class.pre])或
看,措词改变了。现在,在声明类模板的构造函数时,C ++ 20需要注入的类名称。 S< T>
是一个简单的模板ID,用于命名专业化名称。在模板中,注入的类名称只是 S
。
As you can see, the wording changed. C++20 now requires the injected class name when declaring a constructor for a class template. S<T>
is a simple template id that names a specialization. Inside a template, the injected class name is simply S
.
这是解决 CWG 2237 。
这篇关于类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!