简体   繁体   中英

Monitor<T> class implementation in c++11 and c++03?

Herb Sutter describes implementation of template Monitor class in "C++ and Beyond 2012: Herb Sutter - C++ Concurrency":

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

I am trying to wrap my existing class Logger:

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

I have two questions. Why does this code do not compile in Visual Studio 2012 with c++11? Compiler says that " 'Debug' : is not a member of 'monitor' ", where Debug is a method of Logger class.

How to implement the same monitor template class with C++03 compiler using Boost library.

You are likely trying to do something like monitor< Logger >::Debug(...) call. This won't work.

Your monitor can call functions try:

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

PS: I haven't used C++11 lambdas, not to make mistakes I provided boost::bind version

edit : Dave kindly supplied that version

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

Thank you all for answers and comments. There is my implementation of monitor< T > using C++03 and Boost library after your help.

#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 correctness of this solution ( coarse granularity of locks and so on ) I am considering using this class as a wrapper for Google Mock implementation of my ILogger interface in unit tests. Google mock documentation states that it is not thread safe on windows.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM