如何为流式自写类编写用户定义的操纵器

Pet*_* G. 8 c++ iostream

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

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

我的环境是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
Run Code Online (Sandbox Code Playgroud)

PS:接下来只是一个侧面的问题,随意忽略它:这可以扩展到操纵者参与吗?Josuttis在第13.6.1节末尾附近的"C++标准库"中写道,编写操纵器的参与是依赖于实现的.这仍然是真的吗?

Let*_*_Be 2

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

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

    /// 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; }
    };
Run Code Online (Sandbox Code Playgroud)

基于此的操纵器示例:

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; }
Run Code Online (Sandbox Code Playgroud)

一些解释:

  1. 你使用操纵器,它返回绑定到助手实现的助手的新实例
  2. 流尝试处理帮助器,这会调用<<帮助器上的重载
  3. 调用()助手上的运算符
  4. 使用从原始操纵器调用传递的参数来调用帮助程序的实际实现

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