auto&& mit Tücken
« | 25 Jan 2020 | »Dieses auto
ist cool
schrieb ich mal. Und das stimmt auch weiter. Trotzdem muss ich jetzt ergänzen:
Es ist cool, wenn man es richtig einsetzt und nicht mit Vollgas gegen die Wand fährt.
Ich musste mich jetzt wieder mal sehr über mich selbst ärgern.
Ein seltsames Problem trat auf, wobei unter Linux
eine spezielle Dateisuche mit boost::filesystem
fehlschlug, die unter Windows
brav arbeitete.
… oder sagen wir mal, unter Windows im Debug-Modus brav arbeitete …
Nach einer quälenden Suche an den falschen Stellen, landete ich irgendwann bei der Zeile:
1auto&& dirname = dirpath.filename().string();
dirname
beinhaltete nach der Zeile nur noch defekte Datenblöcke.
Hmm … Habe ich nicht mal gesagt, dass auto&&
die beste
Möglichkeit ist, den Rückgabewert einer Funktion generisch anzunehmen?
Ja, das stimmt auch, aber nur wenn der Typ auch stabil bleibt, und das ist in dem Beispiel nicht der Fall.
Denn dirpath.filename()
erzeugt ein neues temporäres Objekt und
.string()
gibt eine konstante String-Referenz auf einen seiner Member
zurück.
auto&&
macht dann genau das, was es gut kann, nämlich den
std::string const &
entgegenzunehmen.
Doch nach dieser Zeile wird das temporäre Objekt von dirpath.filename()
zerstört und die konstante String-Referenz zeigt jetzt auf freigegebenen
ungültigen Speicher.
Fazit
Gefahr erkannt, Gefahr gebannt
würde ich sagen … aber es ärgert mich, dass mir das nicht gleich
aufgefallen ist.
auto&&
ist nur gut, wenn es einen Rückgabewerte der ersten Ebene
direkt erhält, wie z.B.:
auto&& subtext = text.substr(...);
Die Lösung des Code-Problems ist aber einfach:
1auto dirname = dirpath.filename().string();
Hier wird auto
in einen einfachen std::string
aufgelöst, und der bewirkt eine Kopie des Elements aus dem temporären
Objektes.
Diese Kopie überlebt dann auch regulär die Zerstörung der temporären
Instanz und kann gefahrlos weiter eingestetzt werden.
Alternative hätte man aber natürlich auch:
schreiben können. … doch das sieht etwas seltsam aus.