Angenommen, wir haben eine Funktion, die std::optional<A>
zurückgibt. Was ist dann eine geeignete Methode, um das Ergebnis in der bereichsbasierten for-Schleife zu verwenden? Der einfachste Weg nicht funktioniert:Vorübergehend optional in der range-based for loop Ausdruck
for (auto&& e : a().value()) {
// ^--- A&& is returned, so A is destructed
// before loop starts
Dieses Problem würde nicht existieren, wenn wir T optional::value() &&
statt T&& optional::value() &&
hätten, aber beide STL und Boost es in einer zweiten Art und Weise definieren.
Was ist ein geeigneter Weg, um mit dieser Situation umzugehen? Ich mag es nicht, beide Lösungen, die ich von (sandbox) einfiel:
std::experimental::optional<A> a() {
// ...
}
void ok1() {
// ugly if type of A is huge
for (auto&& e : A(a().value())) {
// ...
}
}
void ok2() {
// extra variable is not used
// if for some reason we are sure that we have a value
// and we skip checks
auto&& b = a();
for (auto&& e : b.value()) {
// ...
}
}
// it may be that the best choice is to define
A aForced() {
return A(a().value());
}
Ich schrieb eigentlich eine ganze Post über dieses genaue Verhalten, und ich spreche über verschiedene Optionen, um es in benutzerdefinierten Typen zu lösen, vielleicht finden Sie es interessant: http://www.nirfriedman.com/2016/01/18/schreiben-good-cpp-per-default-in-the-stl /. –
@NirFriedman Ich dachte nie an die gleichen Probleme mit Std :: Get & Co, danke! Und zu Ihrer Information: Der Code, den ich in dieser Frage diskutiere, ist live, also ist Ihr Beitrag wirklich praktisch. Ich verstehe nicht, warum es keine 'std :: copy_of' gibt, als eine Antwort von @ yakk, zumindest wäre es ein guter Weg, Leute dazu zu bringen, auf das Problem zu achten. –