【发布时间】:2014-11-29 00:09:56
【问题描述】:
recent question 让我注意到constexpr has changed in C++14 的方式。新特性是具有静态存储持续时间的非局部变量可以在静态初始化阶段进行初始化,如果其初始化程序由 constexpr 构造函数组成,即使该变量的类型不是文字类型。更准确地说,[basic.start.init] 中的新措辞是:
对象
o的常量初始化器 是一个常量表达式,除了它还可以为o及其子对象调用constexpr 构造函数,即使这些对象不是-literal 类类型 [注意:这样的类可能有一个不平凡的析构函数——尾注]。 常量初始化如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且如果初始化完整表达式是对象的常量初始化器 [...],则执行常量初始化 [...] ]
典型的例子是std::unique_ptr,“不应该比手写更糟糕”:
std::unique_ptr<int> p; // statically initialized by [unique.ptr.single.ctor],
// requires no code excution
int main()
{
p = std::make_unique<int>(100);
}
// p is destroyed eventually
在此添加之前,静态初始化的变量要么是引用类型,要么是文字对象类型,因此具有微不足道的析构函数。但是现在静态初始化的全局变量可以有一个非平凡的析构函数。
相对于动态初始化的全局对象的析构函数,相对于其他静态初始化的析构函数,这样的析构函数调用是如何排序的?析构函数调用是如何排序的?
【问题讨论】:
-
这对 C++14 来说并不新鲜;甚至先前的措辞也允许这样做。 (例如,
std::mutex有一个constexpr构造函数,因此它可以利用静态初始化。) -
@T.C.:感谢您的澄清!
标签: c++ language-lawyer c++14 termination static-initialization