2013-03-15 9 views
5

Herb Sutter opisuje wdrożenie szablonu klasy monitora w "C++ and Beyond 2012: Herb Sutter - C++ współbieżność":Monitorowanie implementacji klasy <T> w językach C++ 11 i 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); } 
}; 

Usiłuję zawinąć moja istniejącej klasy Rejestrator:

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

mam dwa pytania. Dlaczego ten kod nie kompiluje się w Visual Studio 2012 z C++ 11? Kompilator mówi, że "Debuguj": nie jest członkiem "monitora", gdzie Debug jest metodą klasy Logger.

Jak zaimplementować tę samą klasę szablonu monitora przy użyciu kompilatora C++ 03 przy użyciu biblioteki Boost.

+2

Czy wywołujesz 'synchronizedLogger.Debug()' przez przypadek? – juanchopanza

+0

Nie widzę żadnego z twojego kodu używającego czegoś o nazwie 'Debugowanie', więc trudno jest powiedzieć, co to oznacza – PlasmaHH

+4

W związku z tym, myślę, że Sutter stwierdza, że ​​monitor jest rodzajem antystyku, a następnie przedstawia lepsze rozwiązanie. Przygotowałem działającą wersję tego rozwiązania [tutaj] (http://juanchopanzacpp.wordpress.com/2013/03/01/concurrent-object-wrapper-c11/), ale jest to ściśle C++ 11. – juanchopanza

Odpowiedz

8

Prawdopodobnie próbujesz wykonać połączenie typu monitor<Logger>::Debug(...). To nie zadziała.

Monitor może wywołać funkcje spróbować:

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

PS: Nie używałem C++ 11 lambdy, aby nie popełniać błędów I przewidzianych wersja boost :: wiążą

edit: Dave uprzejmie dostarczył tę wersję

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

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

+0

@Dave: czy może zostać udostępniony formularz template-d dla tego połączenia? – user1284631

0

Dziękuję wszystkim dla odpowiedzi i komentarzy. Istnieje moja implementacja monitora < T> przy użyciu biblioteki C++ 03 i Boost po Twojej pomocy.

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

Mówiąc o poprawność rozwiązania (grubej ziarnistości zamki i tak dalej) Jestem rozważa wykorzystanie tej klasy jako otoczka do wdrożenia Google Mock mojego interfejsu ILogger w testach jednostkowych. Dokumentacja próbna Google stwierdza, że ​​nie jest bezpieczna dla wątków w oknach.

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