Was ist string_view?

162

string_viewwurde eine Funktion in den C ++ Library Fundamentals TS ( N3921 ) vorgeschlagen, die zu C ++ 17 hinzugefügt wurde

Soweit ich weiß, handelt es sich um einen Typ, der eine Art "Konzept" einer Zeichenfolge darstellt, bei dem es sich um eine Ansicht eines beliebigen Containertyps handelt, in dem etwas gespeichert werden kann, das als Zeichenfolge angezeigt werden kann.

  • Ist das richtig ?
  • Sollte der kanonische const std::string&Parametertyp werden string_view?
  • Gibt es einen weiteren wichtigen Punkt string_view, der berücksichtigt werden muss?
Drax
quelle
4
Schließlich erkennt jemand, dass Zeichenfolgen eine andere Semantik benötigen, obwohl die Einführung von string_view nur ein kleiner Schritt ist.
John Z. Li

Antworten:

183

Der Zweck aller Arten von Vorschlägen für "Zeichenfolgenreferenz" und "Arrayreferenz" besteht darin, das Kopieren von Daten zu vermeiden, die sich bereits an einem anderen Ort befinden und für die nur eine nicht mutierende Ansicht erforderlich ist. Das string_viewfragliche ist ein solcher Vorschlag; es wurden frühere genannt string_refundarray_ref auch.

Die Idee ist immer, ein Paar von Zeiger auf das erste Element und die Größe eines vorhandenen Datenarrays oder einer vorhandenen Zeichenfolge zu speichern .

Eine solche View-Handle-Klasse könnte billig nach Wert weitergegeben werden und würde billige Teilzeichenfolgenoperationen bieten (die als einfache Zeigerinkremente und Größenanpassungen implementiert werden können).

Viele Verwendungen von Zeichenfolgen erfordern keinen tatsächlichen Besitz der Zeichenfolgen, und die betreffende Zeichenfolge gehört häufig bereits jemand anderem. Es besteht also ein echtes Potenzial zur Steigerung der Effizienz, indem nicht benötigte Kopien vermieden werden (denken Sie an alle Zuordnungen und Ausnahmen, die Sie speichern können).

Die ursprünglichen C-Zeichenfolgen hatten das Problem, dass der Null-Terminator Teil der Zeichenfolgen-APIs war, sodass Sie keine einfachen Teilzeichenfolgen erstellen konnten, ohne die zugrunde liegende Zeichenfolge zu mutieren (a la) strtok ). In C ++ kann dies leicht gelöst werden, indem die Länge separat gespeichert und der Zeiger und die Größe in eine Klasse eingeschlossen werden.

Das einzige Haupthindernis und die Abweichung von der Philosophie der C ++ - Standardbibliothek, die ich mir vorstellen kann, besteht darin, dass solche Klassen mit "referenzieller Ansicht" eine völlig andere Besitzersemantik aufweisen als der Rest der Standardbibliothek. Grundsätzlich ist alles andere in der Standardbibliothek unbedingt sicher und korrekt (wenn es kompiliert wird, ist es korrekt). Mit solchen Referenzklassen stimmt das nicht mehr. Die Richtigkeit Ihres Programms hängt vom Umgebungscode ab, der diese Klassen verwendet. Das ist also schwieriger zu überprüfen und zu lehren.

Kerrek SB
quelle
19
Das Schiff segelte mit dieser Philosophie reference_wrapper, nicht wahr?
Steve Jessop
5
@ KerrekSB Ich fürchte, ich folge nicht. Könnten Sie bitte den Teil "Solche referenziellen Ansichtsklassen haben eine völlig andere Besitzersemantik als der Rest der Standardbibliothek" erweitern ? Mir ist nicht klar: Wie unterscheidet es sich von baumelnden Referenzen / Zeigern? Oder ungültige Iteratoren aufgrund von Einfügung (z. B. std :: vector)? Wir haben diese Probleme bereits. Es ist für mich sehr natürlich, dass eine nicht besitzende Ansicht ähnliche Probleme aufweist wie nicht besitzende Zeiger / Referenzen / Iteratoren.
Ali
5
@Ali: Wenn Sie einen anderen Standardbibliothekscontainer verwenden, können Sie die Richtigkeit des Codes bestätigen, indem Sie sich nur den Code ansehen, der den Container verwendet. Nicht so für string_view. (Ich habe nicht gesagt, dass man niemals kaputten Code schreiben kann. Nur dass die Zerbrochenheit lokal ist .)
Kerrek SB
6
Ich bin überrascht , dass sie nicht mit lief std::rangeaus boost::iterator_range- IMO es ist besser als die string_view Idee
Charles Salvia
19
@nwp: Viele Leute und Sprachen beklagen die schrecklichen Standardeinstellungen von C ++ und denken, dass "const" und "unshared" die Standardeinstellung sein sollten, wobei "mutable" und "shared" die expliziten, seltenen Ausnahmen sind.
Kerrek SB