Also sagt operator[]
nicht direkt, dass s[s.size()]
das Zeichen nach s[s.size()-1]
im Speicher sein muss. Es scheint so zu sein, dass dies vermieden wird.
Aber s.data()
gibt an, dass s.data()+k == &s[k]
und s.data()
einen Zeiger zurückgeben müssen.
Wenn man den scheinbaren Standardfehler der Verwendung von &
auf CharT
oben und nicht std::addressof
ignoriert, kann die Implementierung einen anderen CharT
(z. B. einen auf einer geschützten Seite oder im ROM) für% zurückgeben. co_de% vor dem ersten Aufruf von s[s.size()]
? (Natürlich könnte es den Puffer veranlassen, auf einer schreibgeschützten Seite mit einer Null zu enden; ich spreche über eine andere Situation)
Um explizit zu sein:
Soweit ich sagen kann, wenn s.data()
niemals aufgerufen wird (und der Compiler kann es beweisen), muss s.data()
nicht mit dem Rest des Puffers zusammenhängend sein.
Kann s[s.size()]
ändern nach einem Aufruf von std::addressof(s[s.size()])
und die Implementierung ist standardkonform (solange s.data()
s.data()+k == &s[k]
vor .data()
ausgewertet hat, aber der Compiler ist frei, das zu erzwingen). Oder gibt es Unveränderlichkeitsanforderungen, die ich nicht sehen kann?
Seit C ++ 11 muss std :: string im zusammenhängenden Speicher gespeichert werden. Dies ist das Zitat aus dem C ++ 11 Standard (Abschnitt 24.4.1.4):
Die char-ähnlichen Objekte in a basic_string Objekt soll zusammenhängend gespeichert werden. Das heißt für jeden basic_string Objekt s , Die Identität & amp; * (s.begin () + n) = & amp; * s.begin () + n gilt für alle Werte von n so dass 0 & lt; = n & lt; s.größe () .
Dieses Zitat über den Rückgabewert von operator [] besagt, dass es dasselbe wie &*(s.begin()+n)
(Abschnitt 21.4.5.1) zurückgibt:
* (beginnen () + pos) ob Pos & lt; Größe() . Andernfalls wird eine Referenz auf ein Objekt vom Typ zurückgegeben Diagramm mit Wert Diagramm() , wenn das Ändern des Objekts zu undefiniertem Verhalten führt
Dann haben wir dieses Zitat auf den Rückgabewert von data () in (Abschnitt 24.4.7.1):
Ein Zeiger p so dass p + i == & amp; operator [] (i) für jede ich im [0, Größe ()] .
Die Daten werden also genauso zurückgegeben wie mit dem & amp; -Operator []. Und jeder Wert, den Sie mit dem Operator & amp; abrufen, sollte zusammenhängend gespeichert werden. Sie können also beide schließen einen Zeiger auf zusammenhängende Speicher zurückgeben. Daher wird kein Zeiger auf eine Abstandsseite zurückgegeben.
Beachten Sie, dass dies nur für C ++ 11 gilt. Solche Garantien wurden von der Norm nicht vor C ++ 11 gegeben.
Tags und Links c++ language-lawyer c++14 c++17 stdstring