Ist das zweite Argument für std::getline(std::istream&, std::string&)
sicher und gut definiert? Ein L-Wert, der sich auf eine verschobene std::string
bezieht, und, falls dies der Fall ist, wird diese Zeichenfolge wiederhergestellt Ist der Status "Moved-from" (Ausgezogen) aktiviert, sodass Methoden wie pop_back()
sicher aufgerufen werden können?
Vereinfacht gesagt: Hat das Schreiben in eine Zeichenkette mit getline()
eine äquivalente Semantik, um diese Zeichenkette zuzuweisen?
Oder ist das folgende (etwas erfundene) Snippet wohldefiniert und korrekt?
%Vor% Optimierte ( -march=native -O3
) Builds dieses Snippets mit g++
und clang++
scheinen wie erwartet zu funktionieren, aber das ist natürlich keine Garantie.
Ich würde gerne wissen, ob dies nur auf wohldefiniertes Verhalten gemäß der Semantik von getline()
im C ++ 11-Standard beruht, oder, falls nicht, wenn es durch eine spätere Ausgabe von. gut definiert ist der Standard, oder, wenn nicht, wenn er zumindest explizit durch eine oder alle der wichtigsten Implementierungen definiert ist (G ++, Clang ++, Visual C ++, Intel C ++ Compiler).
Hinweis: Dies ist nicht ein Duplikat früherer Fragen, in dem gefragt wird, ob es sicher ist, einem verschobenen Objekt zuzuweisen (ja, wenn es ein Trivial- oder STL-Typ ist) Weil getline()
nicht der Zuweisungsoperator ist.
Ihr Code ist sicher, aber nur, weil Sie überprüfen, ob getline
erfolgreich etwas in s
gespeichert hat. Wenn die interne Sentry von getline
nicht initialisiert werden konnte, wurde s
nichts zugewiesen und sie würde im Status "valid-but-unspezifiziert" verbleiben. Solange getline
erfolgreich s
auf einen bekannten Status setzt, ist es gut.
Und das allererste, was getline
nach erfolgreicher Sentry-Konstruktion tut, ist s
auf eine Größe von Null (ein bekannter Zustand) zu setzen.
Mehr Details unten in GManNickG Kommentar.
Ist es sicher und wohldefiniert für das zweite Argument, dass
verweist?std::getline(std::istream&, std::string&)
ein lvalue ist, der auf eine verschobene fromstd::string
Ja. Obwohl es die verschobene Zeichenfolge ist, wird sie vom Standard gemäß [string.cons] p2 nicht angegeben :
[...]. In der zweiten Form bleibt
str
in einem gültigen Zustand mit einem unspezifizierten Wert.
Die Zeichenfolge ist immer noch in einem gültigen Zustand, sie ist nur unspezifiziert, d. h. Sie können nicht wissen, in welchem Zustand sie sich befindet (sie kann mit einigen zufälligen Zeichen gefüllt sein). Sie können es weiterhin an std::getline
übergeben, da der Standard in [string.io] p1 Das str.erase()
wird für die Zeichenfolge aufgerufen, die es leert:
[...] ruft
aufstr.erase()
[...]
(wenn der Stream gültig ist, aber ich nehme an, dass dies in Ihrem Fall ist).
Egal was der nicht spezifizierte Zustand des Strings ist, er wird am Anfang von std::getline
geleert, es spielt also keine Rolle, in welchem Zustand er sich befindet.
Eine Zugzuweisung oder eine Bewegung c'tor sollte das bewegte Objekt immer in einem gültigen Zustand belassen.
Im Falle einer std :: string bleibt%% co_de eine gültige, aber nicht spezifizierte Zeichenkette. Aus der Quelle von libc ++:
%Vor% Und da std::move
nur Zeichen an die Zeichenkette anhängt, so lange wie es erfolgreich ist, wird die Ausgabe wie erwartet sein. Von craplus.com :
Beachten Sie, dass jeder Inhalt in str vor dem Aufruf durch die neu extrahierte Sequenz ersetzt wird.
Jedes extrahierte Zeichen wird an die Zeichenkette angehängt, als ob sein Element push_back aufgerufen wurde.