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

时间:2015-10-23 03:54:08

标签: c++ binaryfiles ostream rvalue

我正在尝试在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));

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

1 个答案:

答案 0 :(得分:1)

为了能够以二进制方式轻松输出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