[英]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
函數來做到這一點。 現在我不必擔心這部分代碼的templates
或lambdas
。
這是我想出的函數,我相信它會按適當的順序分配位。
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.