cpp*_*ner 31 c++ language-lawyer constexpr c++17
Consider
struct A1 {
constexpr A1& operator=(const A1&) = default;
~A1() {}
};
struct A2 {
constexpr A2& operator=(const A2&) = default;
~A2() = default;
};
struct A3 {
~A3() = default;
constexpr A3& operator=(const A3&) = default;
};
Run Code Online (Sandbox Code Playgroud)
GCC and MSVC accept all three structs. Clang rejects A1 and A2 (but accepts A3), with the following error message:
Run Code Online (Sandbox Code Playgroud)<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A1& operator=(const A1&) = default; ^ <source>:6:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A2& operator=(const A2&) = default; ^ 2 errors generated.
Which compiler is correct, and why?
Bar*_*rry 24
我认为所有三个编译器都是错误的。
可以声明未定义为delete的显式默认函数,
constexpr或者consteval仅在将其隐式声明为的情况下才声明constexpr。如果一个函数在其第一个声明中被显式默认,则隐式认为该函数constexpr是否为隐式声明。
复制赋值运算符何时隐式声明constexpr?[class.copy.assign] / 10:
如果隐式定义的复制/移动赋值运算符是constexpr,如果
- X是文字类型,并且
- [...]
文字类型在[basic.types] / 10中:
类型是文字类型,如果是:
- [...]
可能具有cv资格的类类型,具有以下所有属性:
- 它有一个琐碎的破坏者,
- [...]
A1没有琐碎的析构函数,因此其隐式副本赋值运算符不是constexpr。因此,该副本分配运算符的格式不正确(gcc和msvc bug可以接受)。
另外两个很好,并且拒绝是一个叮叮当当的错误A2。
请注意我引用的[dcl.fct.def.default]的最后一位。constexpr如果您明确指定了默认值,则实际上不必添加。那将是隐含的constexpr。
C ++ 17标准指出:
15.8.2复制/移动分配运算符[class.copy.assign]
...10当默认使用但未定义为删除的类X的复制/移动赋值运算符时,它被隐式定义(6.2)(例如,当通过重载解析选择它以分配给其类类型的对象时) ),或者在其首次声明后明确将其默认设置。的隐式定义的复制/移动赋值运算符是
constexpr如果
(10.1) -X是一个文本类型,和
(10.2) -选择复制/移动每个直接基类子对象赋值运算符是一个constexpr函数,和
(10.3) -对于每一个非X-类类型(或其数组)的静态数据成员,被选择用来复制/移动该成员的赋值运算符是一个constexpr函数。
复制分配操作员在两种情况下都满足上述要求。在第一种情况下,由于非平凡的析构函数,我们具有非文字类型。
因此,我相信Clang在第二种情况下拒绝代码是错误的。
有一个用Clang归档的bug,标题为:Default destructor阻止在默认的copy / move-operator上使用constexpr,该症状表现出与OP中的代码相同的症状。
错误报告中的注释状态:
当默认的析构函数被注释掉(即未由用户声明)时,错误将不复存在。
和
如果在复制分配运算符之前声明析构函数,该问题也将消失。
问题中的代码也是如此。
正如@YSC所指出的,这里的另一个相关引用是:[dcl.fct.def.default] / 3,其中指出:
可以声明未定义为delete的显式默认函数,
constexpr或者consteval仅在将其隐式声明为的情况下才声明constexpr。如果一个函数在其第一个声明中被显式默认,则隐式认为该函数constexpr是否为隐式声明。
| 归档时间: |
|
| 查看次数: |
1040 次 |
| 最近记录: |