私は、このトークで Herb Sutter のラッパー クラスのアイデアに基づいたシンクロナイザー ヘルパー テンプレート クラスの作成を検討してきました。これは msvc ではそのままでは機能しません (ブレースの初期化を削除しない限り) が、ブレースの初期化が削除されれば問題ありません。 .
clang/gcc (ubuntu 12.10、gcc4.7.2、libc++ で自己ビルドされた clang (3.2)) では、プライベート アクセス修飾子をパブリックの前に表示する必要があるようです。これは少し奇妙に思えます。
gccのエラーは
error: ‘t_’ was not declared in this scope
そしてclangは
error: use of undeclared identifier 't_'
auto operator()(F f) const ->decltype(f(t_))
これは、私が認識していないテンプレート/declytpe の問題である可能性があり、誰かがこの問題を解決できるかどうか疑問に思っています。(関連する c++11 フラグでコンパイルされたすべて)
template <class T>
class Synchronised {
public:
Synchronised(T t = T{}) : t_{t} {}
template <typename F>
auto operator()(F f) const -> decltype(f(t_)) {
std::lock_guard<std::mutex> lock{mutex_};
return f(t_);
}
private: // place this before public: and this object compiles
mutable T t_;
mutable std::mutex mutex_;
};
編集: カット アンド ペーストが必要な場合に備えて、ヨハネスのアイデアと完全なクラスを追加します。
#include <future>
#include <iostream>
#include <thread>
#include <vector>
template <class T> T &self(T &t) { return t; }
template<typename T> struct Dependent { };
template<typename T>
class Synchronised : Dependent<T>{
public:
explicit Synchronised(T t = T()) : t_(t) {}
template<typename Functor>
auto operator()(Functor functor) const ->decltype(functor(self(*this).t_)) {
//auto operator()(Functor functor) const ->decltype(functor(this->t_)) {
std::lock_guard<std::mutex> lock(mutex_);
return functor(t_);
}
private:
mutable T t_;
mutable std::mutex mutex_;
};
int main() {
Synchronised<std::string> sync_string("Start\n");
std::vector<std::future<void>> futures;
}