在下一个程序中,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,而不是一个直接函数上下文。
1条答案
按热度按时间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是错误的)。