首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用std::绑定位字段似乎失败了

使用std::绑定位字段似乎失败了
EN

Stack Overflow用户
提问于 2021-05-07 14:55:06
回答 1查看 131关注 0票数 1

我在C++17中有以下代码,其中我定义了一个struct,它是位掩码,成员变量是bool类型的位字段。

我正在定义一个tie函数,这样我就可以将它转换成一个类似的std::tuple对象,这是很方便的。问题是:std::tie似乎做错了什么,即使默认构造函数正确地将其初始化为true,第一个成员变量的值似乎也是false

手动获取bool对位字段的单个引用似乎如预期的那样工作。

我目前正在使用CLang 12。

这是代码:

代码语言:javascript
复制
#include <cassert>
#include <tuple>

struct Bitmask
{
    Bitmask( )
        : first{true}
        , second{false}
        , third{false}
    {
    }

    bool first : 1;
    bool second : 1;
    bool third : 1;
};

auto
tie( const Bitmask& self )
{
    return std::tie( self.first, self.second, self.third );
}

int main()
{
    Bitmask default_bitmask; 
    Bitmask custom_bitmask;
    custom_bitmask.first = false;
    custom_bitmask.second = true;

    const bool& ref_1 = default_bitmask.first;
    const bool& ref_2 = custom_bitmask.first;

    assert( ref_1 != ref_2 ); // this check works   

    assert( std::get< 0 >( tie( default_bitmask ) ) == true ); // this check fails
    assert( std::get< 0 >( tie( custom_bitmask ) ) == false ); // this check works
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-07 15:10:15

不可能有指向位字段的引用或指针。来自优先选择

因为位字段不一定从字节的开头开始,所以不能接受位字段的地址。对位字段的指针和非const引用是不可能的。当从位字段初始化const引用时,会创建一个临时的(其类型是位字段的类型),复制使用位字段的值初始化,并将引用绑定到该临时字段。

来自标准

运算符&的地址不应应用于位字段,因此没有指向位字段的指针。非连接引用不应绑定到位字段(dcl.init.ref).

附注

[注3:如果const T&类型的引用的初始化器是引用位字段的lvalue,则引用绑定到临时初始化的位字段值;引用不直接绑定到位字段。见dcl.init.ref。-尾注]

这样编译的唯一原因是tieBitmask类型作为const。它的每个位字段成员被视为const,std::tie返回一个const引用的std::tuple。正如上面引用的段落所述,这些引用指的是数据成员的副本,而不是那些实际的数据成员。然后,就像您试图通过引用返回一个const int & x = 10;一样,您最终得到了一个悬空引用的元组。最后,试图获取引用对象的值会导致未定义的行为。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67437232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档