wrapper class for STL stream: forward operator<< calls

本小妞迷上赌 提交于 2019-12-13 18:51:22

问题


I'm currently writing a wrapper for STL stream to synchronize write calls from multiple threads. I have the following (simplified) code:

class Synchronize {
private:
    std::stringstream ss;
public:
    void write(std::string& str) {
        // locking ...
        ss << str;
        // unlocking ...
    };

    // other stuff ..
};

Synchronize& operator<<(Synchronize& o, std::string& str) {
    o.write(str);
    return o;
}

Synchronize& operator<<(Synchronize* o, std::string& str) {
    o->write(str);
    return *o;
}

Its now possible to call the write() method by using the << operator on an object of the Synchronize class, but only by using a std::string. And std::stringstream also takes a lot of other stuff like ints and floats.

Is it possible to add this functionality to my Synchronize class without a ton of own operator<< functions? Would templates help? Or should I extend some class from the iostream library?


回答1:


You can turn your operator overload into a friend template

Inside your class write

template<typename T>
friend Synchronize& operator<<(Synchronize& o, T const& t);

Then the definition could be

template<typename T>
Synchronize& operator<<(Synchronize& o, T const& t) {
    o.write(t);
    return o;
}

 //edit
template<typename T>
void Synchronize::write(T& t)
{
    ss << t;
}



回答2:


If I understand correctly, you want to have many readers into a single destination. The architecture you created (a wrapper on std::stream with synchronized/locked writing) is not a good solution.

Here's code that doesn't work as you would expect:

Synchronize your_stream;

void thread_function1()
{
    output << "this is a message " << "from thread_function1\n";
}
void thread_function2()
{
    output << "this is a message " << "from thread_function2\n";
}

With your code, the output may be:

this is a message this is a message from thread_function2
from thread_function1

What you need is the ability to set synchronization points wherever/whenever you want:

your_stream  out;
out << synchronize_begin << "this is " << " a test" << synchronize_end;

(this buffers everything in a synchronize_begin object (which can be dumped into a stream) and when it receives a synchronize_end object, it locks a mutex (shared with other synchronize_begin instances) and writes to out).

or:

std::ostream  out; // any std::ostream type
out << synchronized << "this is " << " a test"; // synchronized ends here

(synchronized is a buffer instance that exits scope at the end of the line; when it is written into out, it locks, then writes it's data.



来源:https://stackoverflow.com/questions/14752504/wrapper-class-for-stl-stream-forward-operator-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!