cig*_*ien 4 c++ templates constructor language-lawyer c++20
据我所知,以下代码:
template<typename T>
struct S {
S<T>();
};
Run Code Online (Sandbox Code Playgroud)
是格式良好的,即使<T>在构造函数的声明中是多余的。
但是,在 gcc 主干上(但不是在 gcc10.2 上),-std=c++20这会出现错误:
error: expected unqualified-id before ')' token
3 | S<T>();
^
Run Code Online (Sandbox Code Playgroud)
该代码编译的铿锵树干-std=c++20。这是一个错误,还是 C++20 中尚未在所有编译器中实现的重大更改?
事实上,发生了变化。它记录在 C++20 草案的兼容性部分。
[diff.cpp17.class]
2 受影响的子条款:[class.ctor] 和 [class.dtor]
更改:简单模板 ID 不再作为构造函数或析构函数的声明符ID 有效。
基本原理:删除可能容易出错的冗余选项。
对原始特性的影响:有效的 C++ 2017 代码可能无法在此国际标准中编译。例如:Run Code Online (Sandbox Code Playgroud)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 };
具体来说,措辞delta是这样的:
n4659 - C++17 标准草案 - [class.ctor]
1构造函数没有名字。在构造函数的声明中,声明符是形式为的函数声明符
Run Code Online (Sandbox Code Playgroud)ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq其中 ptr-declarator 仅由 id-expression、可选的属性说明符-seq 和可选的括号组成,并且 id-expression 具有以下形式之一:
- 在属于类的成员规范但不是友元声明的成员声明中,id 表达式是直接封闭类的注入类名;
- 在属于类模板的成员规范但不是友元声明的成员声明中, id-expression 是一个类名,用于命名直接封闭类模板的当前实例化;或者
n4861 - C++20 标准草案 - [class.ctor]
1构造函数由一个声明引入,该声明的声明符是一个函数声明符 ([dcl.fct])
Run Code Online (Sandbox Code Playgroud)ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq其中 ptr-declarator 仅由 id-expression、可选的属性说明符-seq 和可选的括号组成,并且 id-expression 具有以下形式之一:
- 在属于类或类模板的成员规范但不是友元声明 ([class.friend]) 的成员声明中,id 表达式是注入的类名 ([class.pre])直接封闭实体或
如您所见,措辞发生了变化。C++20 现在在声明类模板的构造函数时需要注入的类名。S<T>是一个简单的模板 ID,用于命名专业化。在模板中,注入的类名只是S.
这是解决CWG 2237问题的一部分。
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |