consteval 构造函数必须初始化所有数据成员吗?
Must consteval constructor initialize all data members?
在下一个程序中 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
这里是哪个编译器?
来自 cppreference 的 consteval specifier (since C++20):
The consteval specifier declares a function or function template to be
an immediate function,
...
An immediate function is a constexpr function, and must satisfy the
requirements applicable to constexpr functions or constexpr
constructors, as the case may be.
如果我们转到 cppreference 的 constexpr specifier (since C++11):
A constexpr function must satisfy the following requirements:
...
A constexpr constructor whose function body is not =delete; must satisfy the following additional requirements:
...
for the constructor of a class or struct, every base class sub-object
and every non-variant non-static data member must be initialized.
然而,正如@user17732522 在下面的评论中准确指出的那样,最后一个要求仅适用于 直到 C++20。
所以我会说 i
在这种情况下不需要初始化(Clang/MSVC 是正确的,gcc 是错误的)。
在下一个程序中 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
这里是哪个编译器?
来自 cppreference 的 consteval specifier (since C++20):
The consteval specifier declares a function or function template to be an immediate function,
...
An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be.
如果我们转到 cppreference 的 constexpr specifier (since C++11):
A constexpr function must satisfy the following requirements:
...
A constexpr constructor whose function body is not =delete; must satisfy the following additional requirements:
...
for the constructor of a class or struct, every base class sub-object and every non-variant non-static data member must be initialized.
然而,正如@user17732522 在下面的评论中准确指出的那样,最后一个要求仅适用于 直到 C++20。
所以我会说 i
在这种情况下不需要初始化(Clang/MSVC 是正确的,gcc 是错误的)。