c++ - 为什么位模式与 std::bitset 的使用不匹配

标签 c++ output c++17 std-bitset

<分区>

当我对我的类及其构造函数进行单元测试时,我注意到我的输出有些奇怪。

#include <bitset>
#include <cstdint>
#include <iostream>
#include <vector>

typedef std::uint8_t u8;
typedef std::uint16_t u16;
typedef std::uint32_t u32;
typedef std::uint64_t u64;

struct Reg8 {
    std::bitset<8> bits;
    u8 value;

    Reg8() : value{0}, bits{value} {}

    explicit Reg8( u8 val) : value{val}, bits{value} {}
    explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}
    explicit Reg8(u32 val) : value{static_cast<u8>(val)}, bits{value} {}
    explicit Reg8(u64 val) : value{static_cast<u8>(val)}, bits{value} {}    
};

int main() {
    u8  val8  = 24;
    u16 val16 = 24;
    u32 val32 = 24;
    u64 val64 = 24;

    Reg8 r8a(val8);
    Reg8 r8b(val16);
    Reg8 r8c(val32);
    Reg8 r8d(val64);

    std::cout << "Reg8(u8)  r8a value = " << +r8a.value << '\n';
    std::cout << "Reg8(u8)  r8a bits  = " << r8a.bits << "\n\n";

    std::cout << "Reg8(u16) r8b value = " << +r8b.value << '\n';
    std::cout << "Reg8(u16) r8b bits  = " << r8b.bits << "\n\n";

    std::cout << "Reg8(u32) r8c value = " << +r8c.value << '\n';
    std::cout << "Reg8(u32) r8c bits  = " << r8c.bits << "\n\n";

    std::cout << "Reg8(u64) r8d value = " << +r8d.value << '\n';
    std::cout << "Reg8(u64) r8d bits  = " << r8d.bits << "\n\n";

    std::bitset<8> bitsA{ val8 };
    std::cout << "bits value  = " << bitsA.to_ullong() << '\n';
    std::cout << "bits binary = " << bitsA << "\n\n";

    std::bitset<8> bitsB{ val16 };
    std::cout << "bits value  = " << bitsB.to_ullong() << '\n';
    std::cout << "bits binary = " << bitsB << "\n\n";

    std::bitset<8> bitsC{ val32 };
    std::cout << "bits value  = " << bitsC.to_ullong() << '\n';
    std::cout << "bits binary = " << bitsC << "\n\n";

    std::bitset<8> bitsD{ val64 };
    std::cout << "bits value  = " << bitsD.to_ullong() << '\n';
    std::cout << "bits binary = " << bitsD << "\n\n";

    return EXIT_SUCCESS;
}

这是我的输出来自一个小字节序机器和 Intel Quad Core Extreme 运行 Windows 7 x64 并使用 x64 Debug模式下的 Visual Studio 2017 CE,编译器语言选项设置为 c++ 最新草案标准。所有其他编译器标志 - 优化等 Visual Studio 的默认设置。

Reg8(u8)  r8a value = 24
Reg8(u8)  r8a bits  = 11001100

Reg8(u16) r8b value = 24
Reg8(u16) r8b bits  = 11001100

Reg8(u32) r8c value = 24
Reg8(u32) r8c bits  = 11001100

Reg8(u64) r8d value = 24
Reg8(u64) r8d bits  = 11001100

bits value  = 24
bits binary = 00011000

bits value  = 24
bits binary = 00011000

bits value  = 24
bits binary = 00011000

bits value  = 24
bits binary = 00011000

那么为什么类构造中的位模式与 main 中声明的位模式不匹配?

我使用相同的变量类型和值来初始化 main 中的位集以及我的类中的位集,但它们的位模式不匹配。类里的都是一样的,类外的都是一样的。

我期望看到的和我想要的值应该是在 main 中看到的那些。当我查看输出的下半部分时,main 中的这些 bitset 变量的值为 24 并且它们的位模式匹配 24 的 8 位。

0001 1000 = 24

然而,存储在我的类中位集中的位模式不匹配,但包含适当的值。存储在我的类中的位集具有位模式

1100 1100  ... doesn't = 24 in binary

这是怎么回事?

最佳答案

请记住,成员初始化列表按声明顺序进行初始化。这意味着:

struct Reg8 {
    std::bitset<8> bits; // <- first to be initialized in mem-init-list
    u8 value; // <- second

};

并以此构造器为例:

explicit Reg8(u16 val) : value{static_cast<u8>(val)}, bits{value} {}

初始化列表的顺序无关紧要。 bitsvalue 之前在声明中所以 bits将首先被初始化。它将被初始化为 value仍未初始化为 value{static_cast<u8>(val)}bits 的初始化之后出现.

要解决此问题,请交换声明:

struct Reg8 {
    u8 value;
    std::bitset<8> bits;
};

旁注:您缺少一个 stdint包含在您的代码中。

关于c++ - 为什么位模式与 std::bitset 的使用不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56100474/

相关文章:

c++ - 结合 static_cast 和 std::any_cast

c++ - C++中的图像处理

c++ - 如果我们知道参数并返回类型,如何使用其指针调用任何类函数?

c++ - 关于在 C/C++ 中比较整数和 float / double

java - 输入/输出 - 算术方程式

c - 使用指针取消引用生成的模糊输出?

javascript - 将 Javascript 数组输出到 DIV 中

c++ - gcc 中变量模板的错误显式模板特化

c++ - 编译 SDL 测试时出错

c++ - 在C++中在切换情况下使用和不使用 'break'时的不同输出