C ++检查struct中的所有状态位

时间:2017-10-16 14:01:16

标签: c++

我必须将错误状态位作为bool变量存储在struct中。现在我需要一种方法来检查是否设置了任何/ none / all变量。

我知道有std::bitset,但它只允许我按索引而不是按名称访问值。所以我做了这样的结构:

#include <cassert>
union ErrorStatus
{
    struct {
        bool error1;
        bool error2;
        bool error3;
    };
    std::array<bool, 3> bits;
    bool any()const{
        return std::any_of(bits.begin(), bits.end(), [](const bool& b){return b == true; });
        }
    bool none() const {
        return !any();
    }
    bool all()const{
        return !std::any_of(bits.begin(), bits.end(), [](const bool& b){return b == false; });
    }

};

int main(int argc, char** argv)
{

    ErrorStatus errorStatus;
    assert(errorStatus.none() == true);
    errorStatus.error2 = true;
    assert(errorStatus.none() == false);

    return 0;
}

但是我有这个问题,我需要更改std::array声明中的数字,以匹配struct内的布尔值数。

有没有办法将array大小与结构中的bool数量同步? 是否有更优雅的选择(希望阅读更好)?

2 个答案:

答案 0 :(得分:4)

  

是否有更优雅的选择(希望阅读更好)?

您可以使用enum命名数组中的元素:

enum {
  error1,
  error2,
  error3,
  errorsSize // must be last
};

using ErrorStatus = std::array<bool, errorsSize>;

ErrorStatus errors;
errors[error1] = false;

errorsSize之前添加新的枚举器将自动&#34;调整数组大小。

答案 1 :(得分:0)

也许这是一个非常易读的解决方案,它使您的错误结构可用于标准算法:

#include <iostream>
#include <algorithm>

// Configure structure packing for Visual Studio.
// See your compiler documentation on how to do this.
#pragma pack(push)
#pragma pack(1)

struct Errors
{
    bool error1;
    bool error2;
    bool error3;

    inline const bool* begin() const
    {
        return reinterpret_cast<const bool*>(this);
    }

    inline const bool* end() const
    {
        return reinterpret_cast<const bool*>(this + 1);
    }

    inline bool any() const
    {
        return std::count(begin(), end(), true) > 0;
    }

    inline bool all() const
    {
        return std::count(begin(), end(), true) == end() - begin();
    }

    inline bool none() const
    {
        return std::count(begin(), end(), true) == 0;
    }
};

#pragma pack(pop)

我用

进行了测试
int main()
{

    Errors e;
    memset(&e, 0, sizeof(e));

    e.error1 = false;
    e.error2 = false;
    e.error3 = false;
    std::cout << "any=" << e.any() << ", all=" << e.all() << ", none=" << e.none() << std::endl;

    e.error1 = true;
    e.error2 = false;
    e.error3 = false;
    std::cout << "any=" << e.any() << ", all=" << e.all() << ", none=" << e.none() << std::endl;

    e.error1 = true;
    e.error2 = true;
    e.error3 = true;
    std::cout << "any=" << e.any() << ", all=" << e.all() << ", none=" << e.none() << std::endl;

    return 0;
}

但是,这是一个特定于编译器的实现,我不建议以这种方式使用结构。

我最喜欢的存储多个错误代码的方法是

enum class Enum
{
  Error1,
  Error2,
  Error3
};

typedef std::set<Error> Errors;