2013-03-15 7 views
5

Herb Sutter beschreibt die Umsetzung von Template-Monitor-Klasse in "C++ and Beyond 2012: Herb Sutter - C++ Concurrency":Monitor <T> Klassenimplementierung in C++ 11 und 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); } 
}; 

Ich versuche, meine vorhandenen Klasse Logger zu wickeln:

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

Ich habe zwei Fragen. Warum kompiliert dieser Code nicht in Visual Studio 2012 mit C++ 11? Compiler sagt, dass "Debug": kein Mitglied von "Monitor" ist, wo Debug eine Methode der Logger-Klasse ist.

Wie die gleiche Monitor-Vorlagenklasse mit C++ 03-Compiler mit Boost-Bibliothek zu implementieren.

+2

Rufen Sie 'synchronisedLogger.Debug()' auf irgendeine Weise? – juanchopanza

+0

Ich kann nichts von Ihrem Code mit etwas mit dem Namen 'Debug 'sehen, so ist es schwer zu sagen, was es bezieht sich auf – PlasmaHH

+4

Als eine damit verbundene Anmerkung, denke ich, Sutter gibt an, dass der Monitor eine Art von Anti-Muster ist, und präsentiert dann bessere Lösung. Ich habe eine funktionierende Version dieser Lösung [hier] zusammengeschustert (http://juanchopanzacpp.wordpress.com/2013/03/01/concurrent-object-wrapper-c11/), aber es ist streng genommen C++ 11. – juanchopanza

Antwort

8

Sie versuchen wahrscheinlich, etwas wie monitor<Logger>::Debug(...) Aufruf zu tun. Dies wird nicht funktionieren.

Der Monitor kann Funktionen aufrufen try:

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

PS: Ich habe ++ 11 lambdas nicht verwendet C, nicht zu machen Fehler, die ich zur Verfügung gestellt boost :: bind Version

Bearbeiten: Dave freundlicherweise diese Version

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

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

+0

@Dave: Könnte ein Template-d-Formular für diesen Aufruf bereitgestellt werden? – user1284631

0

Vielen Dank an alle für Antworten und Kommentare. Es gibt meine Implementierung von Monitor < T> mit C++ 03 und Boost-Bibliothek nach Ihrer Hilfe. mit dieser Klasse als Wrapper für Google Mock Umsetzung meiner ILogger Schnittstelle in Unit-Tests

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

Talking about Richtigkeit dieser Lösung (grobe Körnung von Schlössern und so weiter) Ich erwäge. In der Google-Dokumentationsdokumentation wird angegeben, dass es unter Windows nicht threadsicher ist.