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

olhwl3o2  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(164)

在下一个程序中,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
这里是哪个编译器?

  • 更新日期:*

我向GCC报告了此问题:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104512并以解释结束
这暗示MSVC和clang都是不正确的。EDG也正确地实现了static_assert,而不是一个直接函数上下文。

ozxc1zmp

ozxc1zmp1#

从cppreference的consteval specifier (since C++20)
consteval说明符将函数或函数模板声明为立即数函数,
...
立即数函数是constexpr函数,必须满足constexpr函数或constexpr构造函数的要求。
如果我们转到cppreference的constexpr specifier (since C++11)
constexpr函数必须满足以下要求:
...
函数体不是=delete的constexpr构造函数;必须满足以下附加要求:
...
对于类或结构的构造函数,必须初始化每个基类子对象和每个非变量非静态数据成员。
然而,正如@user17732522在下面的注解中准确指出的,最后一个要求仅适用于直到C++20
所以我认为i在这种情况下不需要初始化(Clang/MSVC是正确的,gcc是错误的)。

相关问题