string_view
był proponowaną funkcją w C ++ Library Fundamentals TS ( N3921 ) dodanym do C ++ 17
O ile rozumiem, jest to typ, który reprezentuje pewnego rodzaju „koncepcję” ciągu, czyli widok dowolnego typu kontenera, który może przechowywać coś, co można zobaczyć jako ciąg.
- Czy to jest poprawne ?
- Czy
const std::string&
typ parametru kanonicznego powinien stać sięstring_view
? - Czy jest jeszcze jedna ważna kwestia, którą
string_view
należy wziąć pod uwagę?
Odpowiedzi:
Celem wszelkich propozycji „odwołań do ciągów znaków” i „odwołań do tablicy” jest uniknięcie kopiowania danych, które są już w innym miejscu posiadane i dla których wymagany jest tylko niezmutowany widok. Chodzi
string_view
o jedną z takich propozycji; były też wcześniej zwanestring_ref
iarray_ref
.Chodzi o to, aby zawsze przechowywać parę wskaźników do pierwszego elementu i rozmiar jakiejś istniejącej tablicy lub ciągu danych.
Taka klasa uchwytu widoku mogłaby być tanio przekazywana według wartości i oferowałaby tanie operacje na podciągach (które można zaimplementować jako proste przyrosty wskaźnika i dostosowania rozmiaru).
Wiele zastosowań łańcuchów nie wymaga faktycznego posiadania łańcuchów, a dany ciąg często będzie już własnością kogoś innego. Istnieje więc prawdziwy potencjał zwiększenia wydajności poprzez unikanie niepotrzebnych kopii (pomyśl o wszystkich przydziałach i wyjątkach, które możesz zaoszczędzić).
Oryginalne ciągi C cierpiały na problem polegający na tym, że terminator zerowy był częścią interfejsów API ciągów, więc nie można było łatwo tworzyć podciągów bez mutowania podstawowego ciągu (a la
strtok
). W C ++ można to łatwo rozwiązać, przechowując osobno długość i zawijając wskaźnik i rozmiar w jedną klasę.Jedyną główną przeszkodą i rozbieżnością w stosunku do standardowej filozofii biblioteki C ++, o której mogę pomyśleć, jest to, że takie klasy „widoku referencyjnego” mają zupełnie inną semantykę własności niż reszta biblioteki standardowej. Zasadniczo wszystko inne w bibliotece standardowej jest bezwarunkowo bezpieczne i poprawne (jeśli się kompiluje, jest poprawne). W przypadku takich klas referencyjnych nie jest to już prawdą. Poprawność programu zależy od kodu otoczenia, który używa tych klas. Więc trudniej to sprawdzić i uczyć.
źródło
reference_wrapper
, prawda?string_view
. (Nie mówiłem, że nigdy nie możesz pisać zepsutego kodu. Tylko, że zepsuty jest lokalny .)std::range
odboost::iterator_range
- IMO jest lepsze niż pomysł string_view