Herb Sutter asked this question in a talk about C++11 and concurrency (See this video)
The key idea here is to have a non locking class X
where every function call should be decorated with a lock that is unlocked after a function.
However, Herb Sutter drifts then off and presents a functor based approach. I'm wondering if it is even possible with C++11 to wrap each function call with lock and unlock of a class in a generic way (not wrapping every function call manually).
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...
};
there is also the decorator pattern
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;
};
but is there something like this possible:
template<>
class wrap_everything;
wrap_everything<X> x;
x.somefunc(x1,x2,...); // this is then locked.
for the sake of completeness this is herb sutter's functor based approach:
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";
});
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…