为什么不能将析构函数标记为constexpr?

s3r*_*vac 33 c++ language-lawyer constexpr

在C++中,您可以将许多内容声明为constexpr:变量,函数(包括成员函数和运算符),构造函数,以及自C++ 1z以来的if语句lambda表达式.但是,声明析构函数会 constexpr导致错误:

struct X {
    constexpr ~X() = default; // error: a destructor cannot be 'constexpr'
};
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 为什么不能标记析构函数constexpr
  2. 如果我不提供析构函数,是隐式生成的析构函数constexpr吗?
  3. 如果我声明一个默认的析构函数(~X() = default;),它会自动constexpr吗?

Hem*_*war 12

根据草案basic.types#10可能是cv限定的类类型,它具有以下所有属性:

可能具有cv限定的类类型,具有以下所有属性:

(10.5.1) - 它有一个简单的析构函数,

(10.5.2) - 它是一个闭包类型,一个聚合类型,或者至少有一个constexpr构造函数或构造函数模板(可能从一个基类继承),它不是一个复制或移动构造函数,

(10.5.3) - 如果它是一个联合,它的至少一个非静态数据成员是非易失性文字类型

(10.5.4) - 如果它不是联合,则其所有非静态数据成员和基类都是非易失性文字类型.

问题1:为什么析构函数不能被标记为constexpr?

因为只有琐碎的析构函数才有资格获得constexpr以下是草案的相关部分

如果不是用户提供的析构函数是微不足道的,如果:

(5.4) - 析构函数不是虚拟的,

(5.5) - 同类的所有直接基类都有简单的析构函数

(5.6) - 对于类的所有类型(或其数组)的非静态数据成员,每个这样的类都有一个简单的析构函数.

否则,析构函数是非平凡的.

问题2:如果我不提供析构函数,是隐式生成的析构函数constexpr吗?

是的,因为隐式生成的析构函数是微不足道的类型,因此它符合constexpr的条件

问题3:如果我声明一个默认的析构函数(~X()= default;),它会自动constexpr吗?

实际上,这个析构函数是用户声明的并且是隐式生成的,因此它符合constexpr的条件.


我无法找到任何直接引用,只有微不足道destructors的资格,constexpr但如果析构函数不是微不足道,那么确定类类型不是cv-qualified.那么它是隐含的,因为你不能定义destructorfor cv-qualifiedclass.

  • 你能否为这项索赔添加参考资料?_因为只有普通的析构函数才有资格获得constexpr._ (3认同)

saa*_*az1 5

如果您要查找的是限制背后的原因,请查看此文件,其中清楚指出了该限制是人为的 -析构函数没有内在的属性,可以阻止它们在constexpr上下文中工作,实际上编译器实现者同意在constexpr上下文中支持它们将是微不足道的

我猜想C ++标准委员会最初将限制放在C ++ 11中,因为那时他们不想处理析构函数,而将它们完全排除就更容易了。


Cub*_*bic 5

从 C++20 开始,构造函数可以被标记为constexpr; 我不知道 \xe2\x80\x99t 是否明确指出 \xe2\x80\x9ca 析构函数可能是constexpr\xe2\x80\x9d,但标准草案在第 9.2.5 节第 5 段中包含以下文本:

\n\n
\n

constexpr函数体不是的析构函数的定义= delete还应满足\n以下要求:

\n\n
    \n
  • 对于类类型或其(可能是多维)数组的每个子对象,该类类型应具有 constexpr 析构函数。
  • \n
\n
\n\n

这现在也有一个有用的功能,因为 C++20 还允许在上下文中使用newand ,允许像and这样的东西在编译时工作而无需黑客(尽管我相信 C++20 实际上并不包括对标准库的更改以允许这种情况) ,可以使用与以下相同的 API 和行为来实现某些东西deleteconstexprvectorstringvector与编译时完全工作相同的 API 和行为来实现某些东西)。

\n