什么时候构造constexpr对象?

Die*_*ühl 11 c++ constexpr c++11

何时constexpr相对于constexpr具有静态存储持续时间的非非本地对象构造对象?他们是否在初始化任何其他对象之前开始他们的生活,即在动态初始化之前?

我正在考虑使用一个string_literal类(实例)是否合理,例如,将std::strings与某些关键字进行比较:

class string_literal
{
    // private members
public:
    constexpr string_literal(char const* b);
    bool operator== (std::string const& other) const;
    bool operator!= (std::string const& other) const;
    // other member functions
};

constexpr string_literal hello("hello");
void f(std::string const& s) {
    if (s == hello) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

由于string_literal可以在编译时解析字符串文字来定位第一个空字符,我可以想象这些比较可以比比较std::string字符串文字更快.但是,为了安全起见,hello在静态初始化期间在运行时执行第一个构造函数时,必须容易构造对象:否则,当它们尚未构造时,可能会意外地访问这些对象.

Che*_*Alf 7

在C++ 11标准中,非局部变量的初始化顺序在第3.6.2节"非局部变量的初始化"中讨论.

首先执行静态初始化,然后进行动态初始化.

静态初始化包括零初始化, 然后是常量初始化.零初始化正是它听起来的样子.常量初始化是C++ 11中的新增功能,§3.6.2/ 2指定它已执行

  • 如果在具有静态或线程存储持续时间的引用的初始值设定项中出现的每个完整表达式(包括隐式转换)是常量表达式(5.19)并且引用绑定到指定具有静态存储持续时间的对象的左值或临时(见12.2);
  • 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,如果构造函数是constexpr构造函数,如果所有构造函数参数都是常量表达式(包括转换),并且在函数调用替换(7.1.5)之后,每个构造函数mem-initializers中的call和full-expression以及非静态数据成员的brace-or-equal-initializers是一个常量表达式;
  • 如果具有静态或线程存储持续时间的对象未通过构造函数调用初始化,并且其初始化程序中出现的每个完整表达式都是常量表达式.

所以,第二点是constexpr对象可能被初始化的地方,作为静态初始化的最后一部分,并且基本上它发生在所有事情都constexpr可以在编译时知道的情况下.

是的,作为静态初始化的一部分,这在动态初始化之前发生.