3

我正在尝试用C++编写一个自定义I/O 操纵器,它可以根据提供的整数的大小以格式编写格式良好的十六进制。0xFFFF

例如:

  • char c = 1变成0x01
  • short s = 1变成0x0001

等等。在我的代码中找不到错误,即打印垃圾:

#include <iostream>
#include <iomanip>


class hexa_s
{
   mutable std::ostream *_out;

   template<typename T>
   const hexa_s& operator << (const T & data) const
   {
       *_out << std::internal << std::setfill( '0' ) << std::hex << std::showbase << std::setw( sizeof( T ) * 2 ) << data;

       return *this;
   }

   friend const hexa_s& operator <<( std::ostream& out, const hexa_s& b )
   {
       b._out = &out;
       return b;
   }
};

hexa_s hexa( )
{
    return hexa_s( );
}


int main()
{
    int value = 4;

    std::cout << hexa << value << std::endl;

    return 0;
}
4

2 回答 2

3

这条线

std::cout << hexa << value << std::endl;

写入一个指针(指向函数 hexa)。应该调用该函数。

于 2016-03-11T16:39:28.820 回答
1

这绝不是批评。在我看来,写一个 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
于 2016-03-11T17:39:26.000 回答