【问题标题】:How to write user-defined manipulators for streaming self-written class如何为流式自写类编写用户定义的操纵器
【发布时间】:2011-04-28 09:37:32
【问题描述】:

如何在 C++ 中编写用户定义的流操纵器来控制流式传输自写类的格式?

具体来说,我将如何编写简单的操纵器 verboseterse 来控制流式输出的数量?

我的环境是 GCC,版本 4.5.1 及更高版本。

例子:

class A
{
 ...
};

A a;

// definition of manipulators verbose and terse

cout << verbose << a << endl; // outputs a verbosely
cout << terse << a << endl; // outputs a tersely

PS:以下只是一个附带问题,请随意忽略它:这可以移植到接受参数的操纵器吗? Josuttis 在接近 13.6.1 节末尾的“C++ 标准库”中写道,编写带参数的操纵器取决于实现。这仍然是真的吗?

【问题讨论】:

标签: c++ iostream


【解决方案1】:

我认为它们没有任何理由依赖于实现。

这是我使用的东西,对于实际的操纵器,创建一个返回以下帮助器实例的函数。如果您需要存储数据,只需将其存储在 helper、一些全局变量、单例等...

    /// One argument manipulators helper
    template < typename ParType >
    class OneArgManip
    {
        ParType par;
        std::ostream& (*impl)(std::ostream&, const ParType&);

        public:
            OneArgManip(std::ostream& (*code)(std::ostream&, const ParType&), ParType p) 
                : par(p), impl(code) {}

            // calls the implementation
            void operator()(std::ostream& stream) const
            { impl(stream,par); }

            // a wrapper that allows us to use the manipulator directly
            friend std::ostream& operator << (std::ostream& stream, 
                            const OneArgManip<ParType>& manip)
            { manip(stream); return stream; }
    };

基于此的机械手示例:

OneArgManip<unsigned> cursorMoveUp(unsigned c) 
{ return OneArgManip<unsigned>(cursorMoveUpI,c); }

std::ostream& cursorMoveUpI(std::ostream& stream, const unsigned& c)
{ stream << "\033[" << c << "A"; return stream; }

一些解释:

  1. 你使用操纵器,它返回一个新的助手实例,绑定到助手的实现
  2. 流尝试处理助手,它调用助手上的 &lt;&lt; 重载
  3. 调用助手上的() 运算符
  4. 使用从原始操纵器调用传递的参数调用助手的实际实现

如果你愿意,我也可以发布 2 个参数和 3 个参数助手。原理是一样的。

【讨论】:

  • 谢谢,但是我正在考虑影响后续项目如何流式传输的操纵器。
  • @Peter 是一样的。您只需将设置存储在某处。而不是将某些内容输出到您设置 YourClass::outputtype 或类似内容的流中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 2015-06-02
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多