让我们看一下这个代码示例:
class D
{
public:
constexpr D(int val) : i(val) { };
~D() { };
private:
int i;
};
D d(3);
根据文档,D 应该是 constant initialized :
Only the following variables are constant initialized: [...]
2. Static or thread-local object of class type that is initialized by a constructor call, if the constructor is constexpr and all constructor arguments (including implicit conversions) are constant expressions, and if the initializers in the constructor's initializer list and the brace-or-equal initializers of the class members only contain constant expressions.
事实上,d
是通过构造函数调用初始化的,D
的构造函数是constexpr
,我的参数(3
) 是一个常量表达式。
但是,要向编译器指定可以在编译时计算变量的值,可以使用 constexpr
specifier 。但是,在这种情况下,它不会编译,因为 D
不是 LiteralType因为它定义了一个不平凡的构造函数。
那么,在我的代码片段中,d
真的是常量初始化吗?如果是这样,为什么我不能使用 constexpr
说明符?
请您参考如下方法:
So, in my snippet, is
d
really constant initialized? If so, why can't I useconstexpr
specifier?
是的,它将被常量初始化。正如您所引用的,常量初始化不需要类型是 LiteralType。但 constexpr 确实需要它。您的类型不是 LiteralType,因此它不能是 constexpr
。但类型和构造函数调用满足常量初始化的要求。
顺便说一句,C++20 将有 constinit 。这样,您可以确保变量得到静态初始化(这意味着在您的情况下是常量初始化)。
您可以在 godbolt 上查看 constinit 示例。 ,作为编译成功的进一步证据,您可以看到该对象在编译时初始化(不是标准要求,但 GCC 这样做了)。