为什么在类的情况下,从非 constexpr 变量初始化 constexpr 变量会成功

Ala*_*lan 6 c++ constant-expression

我已经了解了constexprC++ 中的变量,并阅读了int i =0; constexpr int j = i;失败的内容,因为i它不是有意义的常量表达式。但是当我对类的变量做同样的事情时,它起作用了。

struct C{};
int main()
{
    int i = 0; //i is not a constant expression as expected 
    //constexpr int j = i; //this fails AS EXPECTED

    C c; 
    constexpr C d = c; //WHY DOESN'T THIS FAIL?? 
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,constexpr C d = c;编译没有任何问题,不像constexpr int j = i;即使c也不是常量表达式。

我想知道这背后的原因。

use*_*570 1

我想知道这背后的原因。

因为该类C有一个隐式constexpr复制构造函数,可以像这样在constexpr 上下文constexpr C::C(const C&)中使用。

基本上,初始化constexpr C d = c;是一个constexpr 上下文,并且 constexpr ctor 正是为了这些目的而设计的。


您还可以通过查看cppinsights中生成的代码来了解这一点:

struct C
{
  // inline constexpr C() noexcept = default;
  // inline constexpr C(const C &) noexcept = default;
};

Run Code Online (Sandbox Code Playgroud)

正如我们在上面生成的代码中看到的,C隐式声明了constexpr可以在 constexpr 上下文中使用的构造函数。


来自constexpr

constexpr 变量必须满足以下要求:

  • ...
  • 其初始化的完整表达式,包括所有隐式转换、构造函数调用等,必须是常量表达式