2013-02-07 37 views
1

我正在编写STL流的包装来同步来自多个线程的写入调用。我有以下(简化的)代码:STL流的包装类:转发运算符<<调用

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; 
} 

它现在有可能通过使用<<操作者Synchronize类的对象上调用的方法write(),但只通过使用std::stringstd::stringstream也需要很多其他的东西,如int s和float s。

是否有可能将此功能添加到我的Synchronize类中而没有自己的一大堆operator<<函数?模板会有帮助吗?或者我应该扩展iostream库中的某个类?

回答

3

你可以把你的操作符重载变成朋友模板

内部类写

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

然后定义可能是

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; 
} 
+1

接受第二。参数为'T const&'。 – Nawaz

+0

@Mogria,是的使它成为一个函数模板,参见我的编辑 –

+0

此外,如果你想支持操纵器,你需要为'operator <<'添加一些额外的重载相应的函数指针。 –

0

如果我理解正确的话,你想拥有许多读者到一个单一的目的地。你创建的体系结构(对std :: stream的包装与同步/锁定写入)不是一个好的解决方案。

这里的代码,你会期望不工作:

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"; 
} 

与您的代码,输出可能是:

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

你需要做的是设置同步点的地方的能力/只要你想:

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

(这缓冲一切在synchronize_begin对象(可以转储到流中)以及当它收到一个对象时,它锁定一个mutex(与其他synchronize_begin实例共享)并写入out)。

或:

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

(同步是离开在该行的末尾范围的缓冲液实例;当它被写入时,它锁定,然后将它写入的数据

+0

谢谢你的回答,但这不是真的如何处理同步nization。这是关于STL流的包装类,以及如何在我的包装器对象上使用'operator <<'时支持更多类型而不仅仅是'std :: string'。 – MarcDefiant