在 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
我试图在 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