#include <string>
#include <iostream>
int main() {
std::string s = "abcdef";
std::string s2 = s;
auto begin = const_cast<std::string const &>(s2).begin();
auto end = s2.end();
std::cout << end - begin << '\n';
}
Dieser Code mischt das Ergebnis von begin() const
mit dem Ergebnis end()
. Keine dieser Funktionen darf Iteratoren ungültig machen. Allerdings bin ich gespannt, ob die Anforderung end()
, die Iterator-Variable begin
nicht ungültig zu machen, tatsächlich bedeutet, dass die Variable begin
mit end
verwendbar ist.Iterator-Invalidierung durch `std :: string :: begin()`/`std :: string :: end()`?
Betrachten Sie eine C++ 98, Copy-on-Write-Implementierung von std::string
; Die nicht-const begin()
und end()
Funktionen verursachen, einen internen Puffer zu kopieren, da das Ergebnis dieser Funktionen zu dem Ändern der Zeichenfolge verwandt werden kann. So beginnt begin
oben für beide s
und s2
, aber die Verwendung der nicht-const end()
Mitglied verursacht es nicht mehr gültig für s2
, der Container, der es produziert.
Der obige Code erzeugt "unerwartete" Ergebnisse mit einer Copy-on-Write-Implementierung, z. B. libstdC++. Anstelle von end - begin
ist das gleiche wie s2.size()
, libstdC++ produces another number.
Hat verursacht
begin
nicht mehr gültig Iterator zu sein ins2
, wobei der Behälter aus abgerufen wurde, darstellen ‚Ungültigkeits‘ den Iterator? Wenn Sie sich die Anforderungen für Iteratoren ansehen, scheinen alle für diesen Iterator zu warten, nachdem.end()
aufgerufen wurde, so dass sichbegin
immer noch als gültiger Iterator qualifiziert und somit nicht ungültig gemacht wurde?Ist der obige Code in C++ 98 gut definiert? In C++ 11, die Copy-on-Write-Implementierungen verbietet?
Aus meiner eigenen kurzen Lesung der Spezifikationen, scheint es unter festgelegtem, so dass es keine Garantie dafür, dass die Ergebnisse der begin()
und end()
immer zusammen verwendet werden können, auch ohne const und nicht-Misch konstante Versionen
Der Grund, warum C++ 11 COW ausdrücklich verboten hat, ist genau dieses Problem: Ihr Code ist konform und sollte "6" ergeben, aber offensichtlich nicht. Die COW-Implementierung ist nicht konform. –
libC++ bekommt das richtig. [Live] (http://coliru.stacked-crooked.com/a/e0d48d1f709b1eb8). –
@BaummitAugen Für eine Definition von "richtig". Der Code in der Frage ist nicht vor C++ 11 legal und funktioniert nicht (oder ist nicht garantiert) mit Bibliotheken vor C++ 11 (einschließlich der Standardbibliothek, die mit g ++ geliefert wird). Die Bibliothek ist nicht falsch, wenn sie fehlschlägt; der Code ist. –