【问题标题】:Bit field initialization in C++20 with `|| new int` construction在 C++20 中使用 `|| 初始化位域新的 int` 构造
【发布时间】:2021-07-23 07:11:21
【问题描述】:

我遇到了关于 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 };
};

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

【问题讨论】:

    标签: c++ c++20 bit-fields


    【解决方案1】:

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

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

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

    () 中的所有内容都被解释为大小说明符。由于“选择了形成有效大小的最长令牌序列”,如 cppreference 所示,因此假设为第二种选择。因此,通过short-circuiting(如果第一个操作数是true,则不计算|| 运算符的第二个操作数),声明相当于

    int z : 1;
    

    位域没有默认值。


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

    在位域的 member-declarator 中,constant-expression 是 被解析为可以在语法上形成的最长的记号序列 一个常量表达式

    在语法上,constant-expression 定义如下:

    常量表达式
    条件表达式

    因此,不接受顶级赋值运算符,但?: 可以。比较链接的 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
    

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

    int x1 : (8) = 42;
    int y1 : (true ? 8 : a = 42);
    

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

    【讨论】:

      猜你喜欢
      • 2019-01-30
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多