2013-03-15 78 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"));