7

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

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

static_assert( B{}.b );

Clang 和 MSVC 都可以。但 GCC 抱怨:

 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

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

哪个编译器在这里?

4

1 回答 1

6

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

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

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

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

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

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

于 2022-02-11T19:51:14.663 回答