在ostream中将右值整数写成二进制值

Write a rvalue integer in a ostream as a binary value

本文关键字:整数 二进制 ostream      更新时间:2023-10-16

我试图在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 <<的包装器类。它可以很容易地被模板化以接受不同大小的积分。例如:

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