这绝不是批评。在我看来,写一个 io 操纵器并不是一件小事。有很多“假设”和“陷阱”。
我可能会选择这样做。你怎么看?
#include <iostream>
#include <utility>
#include <limits>
#include <iomanip>
// in the general case, return a value unchanged
template<class Integral> auto as_integer(Integral i) { return i; }
// but in the case of chars, we must convert them to integers
// otherwise operator<< treats them as characters and does not
// obey the hex iomanipulator
auto as_integer(char c) { return int(c) & 0xff; }
auto as_integer(unsigned char c) { return unsigned(c) & 0xff; }
// This is a basic hex printer for any integral
template<typename Integral>
struct hex_printer
{
static constexpr size_t hex_digits = sizeof(Integral) * 2;
hex_printer(Integral i) : _i(i) {}
std::ostream& operator()(std::ostream& os) const
{
auto flags = os.flags();
try {
os << std::setfill('0') << std::setw(hex_digits) << std::hex << as_integer(_i);
}
catch(...) {
os.flags(flags);
throw;
}
os.flags(flags);
return os;
}
Integral _i;
};
template<typename Integral>
inline std::ostream& operator<<(std::ostream& os, hex_printer<Integral> const& hp)
{
return hp(os);
}
template<typename Integral>
auto neat_hex(Integral i) {
return hex_printer<std::decay_t<Integral>>(i);
}
int main()
{
int x= 0xf045;
short y = 0x6fa;
std::int64_t z = 0xe32;
std::uint8_t w = 0xde;
using namespace std;
cout << neat_hex(x) << " " << neat_hex(y) << " " << neat_hex(z) << " " << neat_hex(w) << endl;
return 0;
}
示例输出:
0000f045 06fa 0000000000000e32 de