C++20 中的位域初始化用`|| 新的 int` 结构

4 c++ bit-fields c++20

我遇到了关于 C++20 位字段初始化https://en.cppreference.com/w/cpp/language/bit_field#Cpp20_Default_member_initializers_for_bit_fields 的页面,其中对于 C++20 存在以下示例(此处简化):

struct S {
    int z : 1 || new int { 0 };
};
Run Code Online (Sandbox Code Playgroud)

该页面没有解释构造|| new int。这里有动态分配new int吗?的默认值z{0}多少,是吗?你能澄清一下吗?

L. *_* F. 7

有两种方法可以解析此声明:

  • int z : (1 || new int) { 0 };

  • int z : (1 || new int { 0 });

里面的所有东西都()被解释为大小说明符。由于如 cppreference 所示,“选择了形成有效大小的最长令牌序列”,因此假设第二个选项。因此,通过短路||如果第一个操作数是true,则不评估运算符的第二个操作数),声明等效于

int z : 1;
Run Code Online (Sandbox Code Playgroud)

位域没有默认值。


可以在[class.mem]/9 中找到管理这种歧义解决的规则:

在位域的成员声明符中,常量表达式被解析为最长的标记序列,可以在语法上形成常量表达式

在语法上,常量表达式定义如下:

常量表达式
?? 条件表达式

因此,不接受顶级赋值运算符,但?:可以。比较链接的 cppreference 页面中的两个示例:

int x1 : 8 = 42;                 // OK; "= 42" is brace-or-equal-initializer
int y1 : true ? 8 : a = 42;      // OK; brace-or-equal-initializer is absent
Run Code Online (Sandbox Code Playgroud)

根据上述规范,它们分别被解析为:

int x1 : (8) = 42;
int y1 : (true ? 8 : a = 42);
Run Code Online (Sandbox Code Playgroud)

其中()再次表示被解析为大小说明符的表达式。