【问题标题】:How do I implement custom stream manipulators taking arguments?如何实现带参数的自定义流操纵器?
【发布时间】:2020-02-22 20:21:56
【问题描述】:

例如,我想要一个流操纵器,我可以将 uint8_t (unsigned char) 传递给并使其输出(例如):

000fa6

我知道可以使用不带参数的流操纵器:

std::ostream &hex_format(std::ostream &out)
{
    out << std::hex << std::setfill('0') << std::setw(2);
    return out;
}

uint8_t x {15};
std::cout << hex_format << static_cast<int>(x); // should produce "0f"

但是我怎样才能创建一个接受参数的操纵器呢?比如:

std::ostream &hex_format(std::ostream &out, uint8_t x)
{
    out << std::hex << std::setfill('0') << std::setw(2)
        << static_cast<int>(x);
    return out;
}

uint8_t x {15};
std::cout << hex_format(x); // (want to) produce "0f"

【问题讨论】:

  • 使它成为一个带有构造函数的类,并存储你的参数;加上重载的operator&lt;&lt; 使用它们。你可以看看std::setfillstd::setw 是如何实现的——它们是接受参数的操纵器。

标签: c++ iomanip


【解决方案1】:

使用操纵器类:

struct hex_format {
    std::uint8_t number;

    hex_format(std::uint8_t x)
        :number{x}
    {
    }
};

然后定义合适的操作符:

template <typename CharT, typename Traits>
decltype(auto) operator<<(std::basic_ostream<CharT, Traits>& os, hex_format rhs)
{
    return os << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(x);
}

题外话:其实这会全局修改流的状态,影响后面的流操作。您可以通过保存状态来解决此问题:

template <typename CharT, typename Traits>
decltype(auto) operator<<(std::basic_ostream<CharT, Traits>& os, hex_format rhs)
{
    auto flags = os.flags();
    os << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(x);
    os.flags(flags);
    return os;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2012-10-11
    • 2020-03-11
    • 2014-05-15
    • 2015-06-02
    相关资源
    最近更新 更多