Herb Sutter задал этот вопрос в разговоре о С++ 11 и concurrency (см. это видео)
Основная идея здесь состоит в том, чтобы иметь класс non-lock X
, где каждый вызов функции должен быть украшен блокировкой, которая разблокирована после функции.
Тем не менее, Херб Саттер затем дрейфует и представляет подход, основанный на функторе. Мне интересно, возможно ли даже с С++ 11 обернуть каждый вызов функции с помощью блокировки и разблокировки класса общим способом (не обматывая каждый вызов функции вручную).
class X {
public:
X() = default;
void somefunc(arg1 x1, arg2 x2, ...);
void somefunc2(arg1 x1, arg2 x2, ...);
/* and more */
};
// herb admits one way to make all functions *available*
// in another class is by derivation
class XX : public X {
public:
XX() = default;
// all functions available in NON overloaded form...
};
существует также узор декоратора
class XXX {
public:
XXX(X &x) : m_x(x) {}
// explicitly call each wrapped function ... done for each class separately.
void somefunc(arg1 x1, arg2 x2, ...);
void somefunc2(arg1 x1, arg2 x2, ...);
private:
class X& m_x;
};
но возможно ли что-то подобное:
template<>
class wrap_everything;
wrap_everything<X> x;
x.somefunc(x1,x2,...); // this is then locked.
для полноты это подход основанный на травяном спутнике:
template <class T> class locker {
private:
mutable T m_t;
mutable std::mutex m_m;
public:
locker( T t = T{} ) : m_t(t) {}
template <typename F>
auto operator()(F f) const -> decltype(f(m_t)) {
std::lock_guard<mutex> _{m_m};
return f(t);
}
};
// usage
locker<std::string> s;
s([](string &s) {
s += "foobar";
s += "barfoo";
});