gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:43:48 28 4
gpt4 key购买 nike

在 C++ 中,您可以将许多内容声明为 constexpr :变量、函数(包括成员函数和运算符)、构造函数,以及从 C++1z 开始,还有 if statementslambda expressions .但是,声明 destructor constexpr 导致错误:

struct X {
constexpr ~X() = default; // error: a destructor cannot be 'constexpr'
};

我的问题:

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

最佳答案

根据 draft basic.types#10可能具有以下所有属性的 cv 限定类类型:

A possibly cv-qualified class type that has all of the following properties:

(10.5.1) - it has a trivial destructor,

(10.5.2) - it is either a closure type, an aggregate type, or has at least one constexpr constructor or constructor template (possibly inherited from a base class) that is not a copy or move constructor,

(10.5.3) - if it is a union, at least one of its non-static data members is of non-volatile literal type

(10.5.4) - if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.

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

因为只有平凡的析构函数才有资格使用 constexpr以下是 draft 的相关部分

A destructor is trivial if it is not user-provided and if:

(5.4) — the destructor is not virtual,

(5.5) — all of the direct base classes of its class have trivial destructors, and

(5.6) — for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.

Otherwise, the destructor is non-trivial.

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

是的,因为隐式生成的析构函数是普通类型,所以符合constexpr的条件

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

事实上,这个析构函数是用户声明和隐式生成的,因此它符合 constexpr 的条件。


我找不到任何直接引用,只有微不足道的 destructors 符合 constexpr 但如果析构函数不是微不足道的,那么它肯定是类类型不是 cv-qualified。 所以它有点隐含,因为你不能为 cv-qualified 类定义 destructor


C++20 更新

自 C++20 起,用户定义的析构函数在某些条件下也可以是 constexpr。

dcl.constexpr/3 :

The definition of a constexpr function shall satisfy the following requirements:

  • its return type (if any) shall be a literal type;
  • each of its parameter types shall be a literal type;
  • it shall not be a coroutine ([dcl.fct.def.coroutine]);
  • if the function is a constructor or destructor, its class shall not have any virtual base classes;
  • its function-body shall not enclose ([stmt.pre])
    • a goto statement,
    • an identifier label ([stmt.label]),
    • a definition of a variable of non-literal type or of static or thread storage duration.

关于c++ - 为什么不能将析构函数标记为 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45071876/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com