7

对于普通对象(即使是对象const),可以通过显式调用析构函数来结束它们的生命周期。稍后,例如,程序可以使用放置在同一内存位置启动另一个对象生命周期new

但是调用constexpr对象的析构函数是否合法?它能否产生一些有用的或至少格式良好的程序?

很容易想象相反的情况:

struct A{
    int v = 0;
    constexpr void foo() { v ? throw 1 : ++v; }
    constexpr ~A() { foo(); }
};

constexpr A y;

int main() { y.~A(); y.~A(); }

这个(很可能是格式错误的)程序被所有编译器接受,没有任何警告:https ://gcc.godbolt.org/z/aqMbfjxKT

在 Clang 中,它通过constexprA.

4

1 回答 1

1

[ dcl.constexpr ]constexpr对象声明中使用的说明符将对象声明为 const。

你可以对这样一个对象做任何你可以对任何其他 const 对象做的事情。constexpr,除了暗示声明对象的常量性之外,似乎不会影响对象本身的任何内容。它只影响程序的静态属性,即哪些表达式是常量表达式,哪些模板实例化是有效的等。对于使用说明符声明的对象的运行时行为没有特殊规定constexpr

该标准多次使用类似于“constexpr object”的短语,但似乎用词不当。在我看来,它应该引用 constexpr 变量。不应该有“constexpr 对象”之类的东西(就像没有内联对象),只有 constexpr 变量(就像有内联变量)。毕竟,constexpr是一个声明说明符,比如inline. 这些变量引用的对象只是 const。

于 2021-08-23T13:51:02.943 回答