constexpr 变量
constexpr 变量必须满足以下要求:
...
它必须不断遭到破坏,即:
它是类类型或其(可能是多维)数组,该类类型具有 constexpr 析构函数,并且对于其唯一作用是销毁对象的假设表达式 e,如果生命周期为该对象及其不可变子对象(但不是其可变子对象)被认为是在 e 内开始的。
我不清楚的部分是 如果一个对象及其不可变子对象(但不是其可变子对象)的生命周期从表达式 e 开始,其唯一作用是销毁该对象,那么e 被认为是核心常量表达式
我想这意味着,比如说像这样的课程
class C{
public:
C(char c):c(c){};
private:
char c;
};
并假设
void foo(){char c; C(c);)
表达式
C(c)
被认为是核心常量,因为通过它创建的对象在;
结束之前生存和消亡? (我承认复制的引用将该表达式描述为“假设”,但标准化委员会肯定会按照上述核心常量表达式的定义设想一个现实的使用场景?同样,上面的示例是人为设计的并且其中所考虑的表达式不仅仅破坏类对象 C;是否有一个用例完全反映了上述核心常量表达式的定义?)
蒂亚
void nocomptime() {};
struct A {
bool b;
constexpr ~A() { if(b) nocomptime(); }
};
然后引用指出以下内容是允许的(任何地方):
constexpr A a{false};
原因是,如果你假设
(这就是引文所考虑的)写道
consteval f() { A a{false}; }
您可以调用
f()
(作为常量表达式,因为它被标记为
consteval
)。这将是一个常量表达式,因为虽然调用了 a
的析构函数,但它被标记为 constexpr
,并且因为 b
是 false
,所以它从不尝试调用 nocomptime
(这会取消对 的整个调用) f()
不再是核心常量表达式,因为它没有标记 constexpr
)。但是,
constexpr A b{true};
格式不正确,因为
consteval g() { A b{true}; }
不可调用(作为常量表达式),因为
b
的析构函数会尝试调用非
constexpr
函数。
在您自己的示例中,C(c)
是
不是常量表达式,因为
c
在常量表达式中不可用。事实上,它没有价值,所以即使它可用,它的使用也会有未定义的行为,因此不符合常量表达式的资格。