我不明白为 constexpr constructor
调用添加的以下内容:
A constant initializer for an object o is an expression that is a constant expression, except that it may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types
Constexpr 构造函数是核心常量表达式本身:
A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
[...]
— an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor (12.4)[...]
最佳答案
后面的注释中有实质性提示:
[ Note: such a class may have a non-trivial destructor — end note ]
回想一下文字类类型 (3.9p10):
- has a trivial destructor,
- is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
- all of its non-static data members and base classes are of non-volatile literal types.
因此,如果一个类有一个非平凡的析构函数,它就没有资格成为文字类,但对其 constexpr 构造函数的调用可能仍然有资格作为常量初始化程序:
#include <iostream>
struct A {
int count = 0;
constexpr A() {}
~A() { std::cout << "~A: " << count << std::endl; }
};
A a;
然后程序可以依赖 a
在任何动态初始化发生之前被初始化,即使 A
不是文字类类型。
这样做的理由是虽然A
的析构函数有副作用,但在初始化期间不会调用它,因此编译器可以计算出适当的编译时 a
的初始内存内容(实际上,它的 .data
)。
请注意,您在第二个引用中的强调是不完整的;相关术语是“a constexpr constructor for a literal class”。
关于c++ - 在常量初始值设定项中调用 constexpr 构造函数的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24492190/