Skip to main content
 首页 » 编程设计

c++之当 T 具有非平凡的析构函数时,类类型 T 的对象可以进行常量初始化吗

2024年02月27日15小虾米

让我们看一下这个代码示例:

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 use constexpr specifier?

是的,它将被常量初始化。正如您所引用的,常量初始化不需要类型是 LiteralType。但 constexpr 确实需要它。您的类型不是 LiteralType,因此它不能是 constexpr。但类型和构造函数调用满足常量初始化的要求。

顺便说一句,C++20 将有 constinit 。这样,您可以确保变量得到静态初始化(这意味着在您的情况下是常量初始化)。

您可以在 godbolt 上查看 constinit 示例。 ,作为编译成功的进一步证据,您可以看到该对象在编译时初始化(不是标准要求,但 GCC 这样做了)。