Herb Sutter ha chiesto questa domanda un parlare di C++ 11 e la concorrenza (vedi this video)Come racchiudere le chiamate di ogni funzione membro di una classe in C++ 11?
L'idea chiave qui è di avere una classe non bloccaggio X
dove ogni chiamata di funzione dovrebbe essere decorato con un blocco che è sbloccato dopo una funzione.
Tuttavia, Herb Sutter si allontana e presenta un approccio basato sul functor. Mi chiedo se è addirittura possibile con C++ 11 per avvolgere ogni chiamata di funzione con blocco e sblocco di una classe in un modo generico (non avvolgendo manualmente ogni chiamata di funzione).
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...
};
c'è anche il modello decorator
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;
};
, ma c'è qualcosa di simile a questo possibile:
template<>
class wrap_everything;
wrap_everything<X> x;
x.somefunc(x1,x2,...); // this is then locked.
per ragioni di completezza questo è l'approccio basato functor di Sutter erba:
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";
});
Almeno con alcuni compilatori (ad es. Gcc) il compilatore può eseguire questa operazione senza alcuna modifica del codice. Solitamente utilizzato per la profilazione, ma è possibile averlo inserire una chiamata a funzioni specificate prima e dopo ogni chiamata di funzione. Sarebbe comunque non banale che il codice risolva il punto in cui si desidera bloccare e dove invece non è vero. –
@JerryCoffin Immagino che sia fatale per ogni manutentore dover cercare i lucchetti da qualche altra parte rispetto al codice. – Alex
@Alex Ottima domanda. Ricordo quando Sutter si allettò con questo al C++ e oltre il 2012, e poi si allontanò, come dici tu. Forse stava lasciando dei suggerimenti sul set di funzionalità del C++ 14. –