consteval 构造函数必须初始化所有数据成员吗?

Fed*_*dor 8 c++ constructor language-lawyer consteval

在下一个程序中,struct B有立即consteval默认构造函数,它不会初始化i字段。然后这个构造函数被用来创建一个临时的并且它的i字段保持不变:

struct B {
    bool b = true;
    int i;
    consteval B() {}
};

static_assert( B{}.b );
Run Code Online (Sandbox Code Playgroud)

Clang 和 MSVC 对此很满意。但海湾合作委员会抱怨道:

 error: 'B{true}' is not a constant expression
    7 | static_assert( B{}.b );
      |                  ^
error: 'B()' is not a constant expression because it refers to an incompletely initialized variable
Run Code Online (Sandbox Code Playgroud)

演示: https: //gcc.godbolt.org/z/x4n6ezrhT

这里是哪个编译器?

更新:

我向 GCC 报告了这个问题:https://gcc.gnu.org/bugzilla/show_bug.cgi? id=104512 并通过解释关闭

这暗示 MSVC 和 clang 确实都不正确。EDG 还正确实现了 static_assert,而不是直接函数上下文。

rtu*_*ado 6

来自 cppreference 的consteval 说明符 (C++20 起)

consteval 说明符将函数或函数模板声明为立即函数,
...
立即函数是 constexpr 函数,并且必须满足适用于 constexpr 函数或 constexpr 构造函数(视情况而定)的要求。

如果我们转到 cppreference 的constexpr 说明符 (C++11 起)

constexpr 函数必须满足以下要求:
...
函数体不为 =delete 的 constexpr 构造函数;必须满足以下附加要求:
...
对于类或结构的构造函数,必须初始化每个基类子对象和每个非变体非静态数据成员。

然而,正如 @user17732522 在下面的评论中准确指出的那样,最后一个要求仅适用于C++20

所以我想说i在这种情况下不需要初始化(Clang/MSVC 是正确的,gcc 是错误的)。

  • 初始化要求仅适用于 C++20 之前的版本。 (2认同)