Ich habe Code, bei dem ein nicht-generischer Lamba-Ausdruck eine lokale statische Variable hat: einen Mutex für einen kritischen Bereich. Etwas, das vereinfacht werden kann:Lokale statische Variable, die zwischen allen Instanzen eines generischen Lambda-Ausdrucks geteilt wird
int i = 0;
auto lambda = [&i](int &v)
{
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
/* critical section with v and i */};
}
nun der kritische Abschnitt in diesem Lambda-Ausdruck umgesetzt könnte auch für andere Typen als int &
wiederverwendet wörtlich und ich würde eine Änderung so einfach gern als int
mit auto
im declarator ersetzen , wie folgt aus:
auto lambda = [&i](auto &v)
Leider, wenn ich das tue, lambda(int&)
und lambda(float&)
die gleiche lokale statische Variable nicht mehr teilen, was die Sperre im kritischen Abschnitt besiegen werden.
Was wäre die einfachste Änderung der Code sein, der all diese Anforderungen erfüllen würde:
- die Genericity liefern, die ich brauche; und
- sicherstellen, dass ich einen einzigen Mutex über alle Instanzen des kritischen Abschnitts geteilt habe; und
- aussetzt nicht die Mutex Öffentlichkeit
Eine Lösung, die den Lambda-Ausdruck zu ersetzen, mit einer Klasse mit einer Template-Methode, so etwas wie das wäre funktionieren würde:
class Lambda
{
public:
Lambda(int &i) : i_(i) {}
template<class V>
void operator()(V &v)
{
std::lock_guard<std::mutex> lock(mutex_);
/* critical section with v and i_ */
};
private:
static std::mutex mutex_;
int &i_;
};
std::mutex Lambda::mutex_;
int i = 0;
Lambda lambda(i);
Dieses würde funktionieren (mit Vorbehalten wie die private Referenz i_
), aber es sieht sehr umständlich im Vergleich zu der ursprünglichen Lambda-Ausdruck. Wäre es etwas einfacher?
Diese So hat er keinen einzigen Mutex über alle Instanzen des kritischen Abschnitts hinweg *. Liege ich falsch? – skypjack
@skypjack, oops, ich habe ursprünglich 'make_shared' geschrieben, aber ich bin nicht sicher, warum ich es in' make_unique' geändert habe (was das Lambda nicht kopierbar macht, wenn ich es mit einem geteilten Mutex kopierbar machen wollte). Ein dummer Brainfart. Jetzt behoben. –
Schön. Ich denke, das OP möchte auch '(auto & v)' anstelle von '(int & v)' sehen, denn es war sein Ziel, ein generalisiertes Lambda zu haben. – skypjack