c++ - 在常量初始值设定项中调用 constexpr 构造函数的限制

标签 c++

我不明白为 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/

相关文章:

c++ - 在 C++ 中重组 vector

c++ - C++ 中前向声明的类

c++ - boost::weak_ptr<T>.lock() 因 SIGSEGV 段错误而崩溃

c++ - std::remove 指定元素的 vector

c++ - 在运行时添加自定义 QWidget

c++ - 从 C/C++ 库中解压缩可执行文件

c++ - OpenALPR 退出并出现带有自定义训练数据的段错误

c++ - 在链表前面添加节点

c++ - 在 QTCreator Undefined Reference 中使用库

c++ - 使用 fgets() 时出错