Scott Meyers, in Effektive Moderne C++, sagt, bei Lambda Kapitel, dass baumeln lassen konnte: istLambda: Ein Neben Referenzeinfangliganden die
void addDivisorFilter()
{
auto calc1 = computeSomeValue1();
auto calc2 = computeSomeValue2();
auto divisor = computeDivisor(calc1, calc2);
filters.emplace_back(
[&](int value) { return value % divisor == 0; }
);
}
Dieser Code:
Betrachten Sie den folgenden Code ein Problem, das darauf wartet, zu passieren. Das Lambda bezieht sich auf die lokale Variable
divisor
, aber diese Variable hört auf zu existieren, wennaddDivisorFilter
zurückkehrt. Das ist sofort nachfilters.emplace_back
zurück, so dass die Funktion, diefilters
hinzugefügt wird, im Wesentlichen bei der Ankunft tot ist. Die Verwendung dieses Filters führt zu undefiniertem Verhalten ab dem Zeitpunkt der Erstellung.
Die Frage ist: Warum ist es ein undefiniertes Verhalten? Soweit ich weiß, wird filters.emplace_back
erst zurückgegeben, nachdem der Lambda-Ausdruck abgeschlossen ist und während der Ausführung divisor
gültig ist.
aktualisieren
Eine wichtige Daten, die ich verpasst habe zu zählen ist:
using FilterContainer = std::vector<std::function<bool(int)>>;
FilterContainer filters;
Verwenden der OP-Funktion Beispiel, wenn ich Filter durch 'mit FilterContainer = std :: vector definieren;' Diese Referenz könnte baumeln? –
Amadeus
@Amadeus Wenn er den 'bool' speichert, müsste er sich nicht mit der Dangling-Referenz befassen, da alle' std :: vector' '' true'/'false' Werte enthalten würden. Aber er speichert 'std :: function' und gibt' bool' zurück, und der Rückgabewert hängt vom Divisor ab und er benötigt ihn, um den 'bool' Rückgabewert zu berechnen. –
@Amadeus Stellen Sie sicher, dass alles, was im Vektor gespeichert ist, keine überlebten Referenzen speichert. – vsoftco