2013-03-15 8 views
5

Herb Sutter descrive l'implementazione del modello di classe Monitor in "C++ e oltre 2012: Herb Sutter - C++ Concurrency":Monitoraggio dell'implementazione della classe <T> in C++ 11 e 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); } 
}; 

Sto cercando di avvolgere la mia classe esistente Logger:

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

ho due domande. Perché questo codice non viene compilato in Visual Studio 2012 con C++ 11? Il compilatore dice che "Debug": non è un membro di "monitor" ", dove Debug è un metodo della classe Logger.

Come implementare la stessa classe di modello di monitoraggio con il compilatore C++ 03 utilizzando la libreria Boost.

+2

Stai chiamando 'synchronizedLogger.Debug()' per caso? – juanchopanza

+0

Non riesco a vedere alcun codice usando qualcosa chiamato "Debug", quindi è difficile dire a cosa si riferisce – PlasmaHH

+4

Come nota correlata, penso che Sutter affermi che il monitor è una sorta di anti-pattern, e quindi presenta un soluzione migliore Ho messo insieme una versione funzionante di questa soluzione [qui] (http://juanchopanzacpp.wordpress.com/2013/03/01/concurrent-object-wrapper-c11/), ma è rigorosamente C++ 11. – juanchopanza

risposta

8

Probabilmente stai provando a fare qualcosa come la chiamata monitor<Logger>::Debug(...). Questo non funzionerà.

Il monitor può richiamare le funzioni prova:

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

PS: Non ho usato C++ 11 lambda, per non commettere errori che ho fornito la versione boost :: bind

modifica: Dave ha gentilmente fornito quella versione

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

'logger ([] (Logger & l) {l.Debug (" blah ");});' – David

+0

@Dave: potrebbe essere fornito un modello di modulo per questa chiamata? – user1284631

0

Grazie a tutti voi per risposte e commenti. C'è la mia implementazione del monitor < T> utilizzando C++ 03 e la libreria Boost dopo il vostro aiuto.

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

Parlando di correttezza di questa soluzione (granularità grossolana di serrature e così via) che sto considerando se usare questa classe come un wrapper per l'implementazione di Google Mock della mia interfaccia ILogger in unit test. Google mock documentation afferma che non è thread-safe su Windows.

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