I'm trying to output an integer as binary in a std::ostream
.
The first thing I tried was:
int MyInt(){return 42;}
//...
std::ostream out; //not actually this but any ostream will do
out<<MyInt();
This of course converts the int
to a character string which isn't what I want.
I also found a way to make it work:
int value=MyInt();
out.write(reinterpret_cast<const char*>(&value), sizeof(int));
This outputs what I want however I have to use a temporary to hold the value while using the function directly like this:
out.write(reinterpret_cast<const char*>(&(MyInt())), sizeof(int));
Will fail to compile because I can't take the address of a rvalue
(unless it's bound to a const reference).
This made me try that:
out.write(&(const char&)(MyInt()), sizeof(int));
However while it does preserve the smallest byte the other ones are garbage. The results are also probably implementation-defined as far as I know so not a recommended solution even if it were to work.
A union
can solve the problem and is probably nicer than a temporary variable.
union IntConverter{
int i;
char c[sizeof(int)];
IntConverter(int in) :i(in){}
};
out.write(IntConverter(MyInt()).c, sizeof(int));
However, I would like to avoid having to write more code if possible and I'm out of ideas so I am asking if there is a better solution to solve this problem.
To be able to easily output an int in binary, I would use a wrapper class with a friend operator <<
. It could easily be templated to accept integral of different sizes. For example:
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;
}
};
You can use it as simply as:
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;
and on a 32 bits little endian it gives:
Val:1094861636 - repr:DCBA
Val:17734 - repr:FE