我不理解constexpr constructor
调用的以下内容:
对象o的常量初始值设定项是一个表达式 常量表达式,除了它还可以调用 constexpr o及其子对象的构造函数,即使这些对象是 非文字类类型
Constexpr构造函数本身是核心常量表达式:
条件表达式e是核心常量表达式,除非 评估e,遵循抽象机的规则(1.9), 将评估以下表达式之一:
[...]
- 一个调用 对于文字类,函数而不是constexpr构造函数, constexpr函数,或者是一个简单的隐式调用 析构函数(12.4)[...]
答案 0 :(得分:0)
随后的说明中有一些实质性暗示:
[注意:这样的类可能有一个非平凡的析构函数 - 结束语]
回想一下文字类型(3.9p10):
- 有一个简单的析构函数,
- 是聚合类型(8.5.1)或至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,而且
- 它的所有非静态数据成员和基类都是非易失性文字类型。
因此,如果一个类有一个非平凡的析构函数,它就被取消了作为文字类的资格,但是对其constexpr构造函数的调用仍然可以作为一个常量初始化程序:
#include <iostream>
struct A {
int count = 0;
constexpr A() {}
~A() { std::cout << "~A: " << count << std::endl; }
};
A a;
然后,即使a
不是文字类类型,程序也可以在进行任何动态初始化之前依赖A
进行初始化。
基本原理是因为虽然A
的析构函数有副作用,但在初始化期间不会调用它,因此编译器可以计算适当的初始内存内容在编译时a
(实际上,它是.data
)。
请注意,您在第二个引用中的重点是不完整的;相关术语是“一个constexpr构造函数,用于文字类 ”。