5

Herb Sutter は、「C++ and Beyond 2012: Herb Sutter - C++ Concurrency」でテンプレート Monitor クラスの実装について説明しています。

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 logger;
monitor< Logger > synchronizedLogger( logger ) ;

2 つの質問があります。このコードが Visual Studio 2012 with c++11 でコンパイルされないのはなぜですか? Compiler は、「 'Debug' : is not a member of 'monitor' 」と言います。ここで、Debug は Logger クラスのメソッドです。

Boost ライブラリを使用して C++03 コンパイラで同じ監視テンプレート クラスを実装する方法。

4

2 に答える 2

8

monitor< Logger >::Debug(...)あなたはおそらくcallのようなことをしようとしています。これはうまくいきません。

モニターは関数を呼び出すことができます:

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

PS:私は C++11 ラムダを使用していません。間違いを犯さないようにするためです。boost::bind バージョンを提供しました。

編集:デイブは親切にそのバージョンを提供しました

logger([](Logger& l){ l.Debug("blah"); });
于 2013-03-15T14:54:45.247 に答える
0

回答とコメントをありがとうございました。あなたの助けを借りて、C++03 と Boost ライブラリを使用した私の monitor< T > の実装があります。

#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 実装のラッパーとして使用することを検討しています。Google モック ドキュメントには、Windows ではスレッド セーフではないと記載されています。

 ILogger * mockedLogger = new MockedLogger();
 monitor< ILogger > synchronizedLogger( *mockedLogger ) ;
 synchronizedLogger( boost::bind( &ILogger::Debug, _1, "blah" ) );
于 2013-03-19T08:37:28.557 に答える