2013-03-15 80 views
5

香草萨特描述的实施模板Monitor类的 “C++和2012年之后:香草萨特 - C++并发”:监视器<T> C++ 11和C++ 03中的类实现?

template<class T> class monitor { 
private: 
    mutable T t; 
    mutable std::mutex m; 
public: 
    monitor(T t_) : t(t_) { } 

    template<typename F> 
    auto operator()(F f) const -> decltype(f(t)) 
    { std::lock_guard<mutex> hold{m}; return f(t); } 
}; 

我想换我现有的类记录仪:

Logger logger; 
monitor<Logger> synchronizedLogger(logger) ; 

我有两个问题。 为什么此代码不能在Visual Studio 2012中用C++ 11编译? 编译器说“'调试':不是'监视器'的成员,其中调试是Logger类的一种方法。

如何用C++ 03编译器使用Boost库实现相同的监视器模板类。

+2

你是否正在调用'synchronizedLogger.Debug()'? – juanchopanza 2013-03-15 14:50:46

+0

我看不到任何使用'Debug'命名的代码,所以很难说明它的含义 – PlasmaHH 2013-03-15 14:56:17

+4

作为一个相关说明,我认为Sutter说监视器是一种反模式,然后呈现一个解决方案更好我拼凑了一个该解决方案的工作版本[在这里](http://juanchopanzacpp.wordpress.com/2013/03/01/concurrent-object-wrapper-c11/),但它完全是C++ 11。 – juanchopanza 2013-03-15 15:06:36

回答

8

您可能试图执行类似monitor<Logger>::Debug(...)的呼叫。这不起作用。

您的显示器可以调用的函数 尝试:

monitor<Logger> logger; 
logger(boost::bind(&Logger::Debug, _1, "blah")); 

PS:我没有使用C++ 11个lambda表达式,不要让我犯错误提供的boost ::绑定版

编辑:戴夫友善地提供该版本

logger([](Logger& l){ l.Debug("blah"); }); 
+7

'Logger([](Logger&l){l.Debug(“blah”);});' – David 2013-03-15 15:53:43

+0

@Dave:是否可以为此调用提供模板d表单? – user1284631 2014-10-15 12:42:58

0

谢谢大家寻求答案和评论。 在您的帮助之后,我使用C++ 03和Boost库实现了监视器<。

#include <boost/bind.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/thread/locks.hpp> 
#include <boost/utility/result_of.hpp> 

template<class T> class monitor 
{ 
private: 
    mutable T& t; 
    mutable boost::mutex m; 
public: 
    monitor(T& t_) : t(t_) 
    { 
    } 

    template< typename F > 
    typename boost::result_of< F() >::type operator()(F f) const 
    { 
      boost::lock_guard<boost::mutex> hold(m); 
      return f(t); 
    } 
}; 

谈起这个解决方案的正确性(锁的粗粒度等)我使用这个类用作单元测试谷歌模拟实现我的ILogger接口的包装考虑。 Google mock文档指出,它在Windows上不是线程安全的。

ILogger * mockedLogger = new MockedLogger(); 
monitor<ILogger> synchronizedLogger(*mockedLogger) ; 
synchronizedLogger(boost::bind(&ILogger::Debug, _1, "blah"));