让我们看一下这个代码示例:
class D
{
public:
constexpr D(int val) : i(val) { };
~D() { };
private:
int i;
};
D d(3);
根据文档,D 应该常量初始化:
只有以下变量被常量初始化:[...]
2. 类类型的静态或线程本地对象,由 构造函数调用,如果构造函数是 constexpr 并且所有构造函数 参数(包括隐式转换(是常量表达式, 如果构造函数的初始值设定项列表中的初始值设定项和 类成员的大括号或等于初始值设定项仅包含常量 表达 式。
事实上,d
是通过构造函数调用初始化的,D
的构造函数是constexpr
的,我的参数(3
(是一个常量表达式。
但是,要向编译器指定可以在编译时计算变量的值,可以使用constexpr
说明符。但是,在这种情况下,它不会编译,因为D
不是LiteralType,因为它定义了一个重要的构造函数。
那么,在我的片段中,d
真的是常量初始化的吗?如果是这样,为什么我不能使用constexpr
说明符?
那么,在我的片段中,
d
真的是常量初始化的吗?如果是这样,为什么我不能使用constexpr
说明符?
是的,它将不断初始化。正如你所引用的,常量初始化不需要类型是 LiteralType。但constexpr
确实需要它。您的类型不是文本类型,因此它不能是constexpr
。但是类型和构造函数调用满足常量初始化的要求。
顺便说一句,C++20 将持续存在。有了这个,您可以确保变量得到静态初始化(这意味着在您的情况下进行常量初始化(。
你可以在 godbolt 上查看你的示例的 constinit,作为它成功编译的进一步证据,你可以看到对象是在编译时初始化的(不是标准的要求,但 GCC 做到了(。