簡體   English   中英

是否有一種簡單有效的方法將 bool [8] 的值分配給 std::uint8_t

[英]Is there an easy and efficient way to assign the values of bool [8] to std::uint8_t

考慮以下變量:

std::uint8_t value;

const bool bits[8] = { true, false, false, true,
                       false, false, true, false };

如果我要將布爾數組打印到控制台

for (int i = 0; i < 7; i++ )
    std::cout << bits[i];

它將給出以下輸出:

10010010

足夠簡單和直接。


我想要做的是生成一個 constexpr 函數、一個函數模板、一個 lambda 或它們的組合,它們可以在編譯時或運行時運行,具體取決於它被用於我可以采取的上下文每個布爾值 0 和 1 並將它們存儲到上面的變量value 如果該值在編譯時已知,那么我希望解決此分配問題。 如果該值在編譯時未知,則該值將被初始化為 0,直到它被更新,然后它將在運行時上下文中使用。

但是,有一個警告一開始並不明顯,但是通過對數組進行索引,數組的第 0索引將是該value的 LSB 位,第 7索引將是 MSB。 因此,您從屏幕上看到的位順序將具有 0x92 的十六進制值,但要存儲的值需要是 01001001,它的十六進制值為 0x49 或十進制 73 而不是 146。

以上是一個類中的成員,其中一個是數據值表示,布爾數組是位表示。 我有一些構造函數,其中一個將直接設置數據或值成員,而其他構造函數將設置 bool 數組,但是如果一個更新,我需要這兩個值在類對象的整個生命周期中彼此​​保持並發另一個也需要改變。 此外,bools 數組是一個無名聯合的成員,具有 8 個單獨的 bool 的無名結構作為位字段中的一個位。 該類還有一個索引運算符,可以將各個位作為 0 或 1 的單個布爾值訪問。


這是我的班級的樣子:

constexpr unsigned BIT_WIDTH(const unsigned bits = 8) { return bits; }

struct Register_8 {
    union {
        bool bits_[BIT_WIDTH()];
        struct {
            bool b0 : 1;
            bool b1 : 1;
            bool b2 : 1;
            bool b3 : 1;

            bool b4 : 1;
            bool b5 : 1;
            bool b6 : 1;
            bool b7 : 1;
        };
    };

    std::uint8_t data_;   

    Register_8() : data_{ 0 } {}
    Register_8(std::uint8_t data) : data_{ data } {

    }

    Register_8(const bool bits[BIT_WIDTH()]) {
        for (unsigned i = 0; i < 8; i++)
            bits_[i] = bits[i];
    }

    Register_8(const bool a, const bool b, const bool c, const bool d,
        const bool e, const bool f, const bool g, const bool h) {
        b0 = a; b1 = b, b2 = c, b3 = d;
        b4 = e, b5 = f, b6 = g, b7 = h;
    }

    const std::uint8_t operator[](std::uint8_t idx) {
        // I know there is no bounds checking here, I'll add that later!
        return bits_[idx];
    }
};

那么如何使bits[]中的每個value成為value的單個位,其中bit[0]value的 LSB? 我還想在不會生成任何 UB 的上下文中執行此操作! 或者在 C++17 下的STL中是否已經存在一種算法可以為我做到這一點? 我還沒有 C++20 編譯器......我已經嘗試在union包含std::uint8_t但它不起作用,因為我也喜歡它,我也不希望它起作用!

我離開了一會兒,然后又回到了我正在做的事情上……我認為短暫的休息有所幫助。 用戶Nicol Bolas的建議也幫助我知道我可以使用constexpr函數來做到這一點。 現在我不必擔心這部分代碼的templateslambdas

這是我想出的函數,我相信它會按適當的順序分配位。

constexpr unsigned BIT_WIDTH(const unsigned bits = CHAR_BIT) { return bits; }

constexpr std::uint8_t byte_from_bools(const bool bits[BIT_WIDTH()]) {
    std::uint8_t ret = 0x00;
    std::uint8_t pos = 0x00;
    for (unsigned i = 0; i < BIT_WIDTH(); i++) {
        ret |= static_cast<std::uint8_t>(bits[i]) << pos++; // << pos--;
    }
    return ret;
}

如果有任何可以進行的優化或任何錯誤或代碼異味,請告訴我...


現在,只需提取單個位並將它們分配給我的位域成員,並跟蹤其中任何一個更改以確保兩者以並發方式更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM