如何为流化自写类编写用户定义操纵符

How to write user-defined manipulators for streaming self-written class

本文关键字:用户 定义 操纵      更新时间:2023-10-16

如何在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在"c++标准库"第13.6.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 << "33[" << c << "A"; return stream; }

说明:

  1. u使用操纵符,它返回绑定到helper
  2. 实现的helper的新实例。
  3. 流试图处理helper,这会调用helper上的<<过载
  4. 调用助手上的()操作符的
  5. ,它使用从原始操纵符调用
  6. 传递的参数调用helper的实际实现。

如果你想,我可以发布2参数和3参数的帮助以及。原理是一样的