在 ostream 中写入一个右值整数作为二进制值

Write a rvalue integer in a ostream as a binary value

我试图在 std::ostream 中输出一个整数作为二进制。

我尝试的第一件事是:

int MyInt(){return 42;}
//...
std::ostream out; //not actually this but any ostream will do
out<<MyInt();

这当然会将 int 转换为一个字符串,这不是我想要的。

我也找到了让它工作的方法:

int value=MyInt();
out.write(reinterpret_cast<const char*>(&value), sizeof(int));

这会输出我想要的结果,但是我必须使用一个临时变量来保存值,同时直接使用函数,如下所示:

 out.write(reinterpret_cast<const char*>(&(MyInt())), sizeof(int));

将无法编译,因为我无法获取 rvalue 的地址(除非它绑定到 const 引用)。

这让我尝试了:

out.write(&(const char&)(MyInt()), sizeof(int));

然而,虽然它确实保留了最小的字节,但其他字节都是垃圾。据我所知,结果也可能是实现定义的,因此即使可行,也不是推荐的解决方案。

一个union可以解决问题,而且可能比临时变量更好。

union IntConverter{
    int i;
    char c[sizeof(int)];
    IntConverter(int in) :i(in){}
};
out.write(IntConverter(MyInt()).c, sizeof(int));

但是,如果可能的话,我想避免不得不编写更多的代码,而且我没有想法,所以我想问一下是否有更好的解决方案来解决这个问题。

为了能够轻松地以二进制形式输出 int,我会与朋友 operator << 一起使用包装器 class。它可以很容易地被模板化以接受不同大小的积分。例如:

template<typename T>
class BinInt {
private:
    T i;

public:
    BinInt(T i): i(i) {}
    friend std::ostream& operator << (std::ostream& os, const BinInt& b) {
        os.write(reinterpret_cast<const char *>(&(b.i)), sizeof(T));
        return os;
    }
    T val() {
        return i;
    }
};

您可以像这样简单地使用它:

BinInt<int> bi(0x41424344);
BinInt<short> bs(0x4546);
std::cout << "Val:" << bi.val() << " - repr:" << bi << std::endl;
std::cout << "Val:" << bs.val() << " - repr:" << bs << std::endl;

在 32 位小字节序上它给出:

Val:1094861636 - repr:DCBA
Val:17734 - repr:FE