Overload handling of std::endl?

后端 未结 7 997
广开言路
广开言路 2020-11-27 04:40

I want to define a class MyStream so that:

MyStream myStream;
myStream << 1 << 2 << 3 << std::endl << 5 << 6         


        
7条回答
  •  一整个雨季
    2020-11-27 05:03

    Agreed with Neil on principle.

    You want to change the behavior of the buffer, because that is the only way to extend iostreams. endl does this:

    flush(__os.put(__os.widen('\n')));
    

    widen returns a single character, so you can't put your string in there. put calls putc which is not a virtual function and only occasionally hooks to overflow. You can intercept at flush, which calls the buffer's sync. You would need to intercept and change all newline characters as they are overflowed or manually synced and convert them to your string.

    Designing an override buffer class is troublesome because basic_streambuf expects direct access to its buffer memory. This prevents you from easily passing I/O requests to a preexisting basic_streambuf. You need to go out on a limb and suppose you know the stream buffer class, and derive from it. (cin and cout are not guaranteed to use basic_filebuf, far as I can tell.) Then, just add virtual overflow and sync. (See §27.5.2.4.5/3 and 27.5.2.4.2/7.) Performing the substitution may require additional space so be careful to allocate that ahead of time.

    - OR -

    Just declare a new endl in your own namespace, or better, a manipulator which isn't called endl at all!

提交回复
热议问题