Klasa std::string_view¶
Nagłówek:
<string_view>
Lekki uchwyt dla sekwencji znaków (read-only)
czas życia danych (bufora znaków) nie jest kontrolowany przez obiekt typu
string_view
string_view good("text literal"); // OK - internal pointer points to static array string_view bad("string literal"s); // BAD - internal pointer is a dangling pointer
brak wsparcia dla alokatorów - nie są potrzebne
przekazywanie przez wartość jest efektywne
typowa implementacja: wskaźnik na stały znak (
const char*
) i rozmiar
Zdefiniowane są również odpowiedniki dla innych typów znakowych niż
char
:std::wstring_view
- dla typuwchar_t
std::u16string_view
- dla typuchar16_t
std::u32string_view
- dla typuchar32_t
Literał:
sv
- zdefiniowany w nagłówku
<literals>
- zdefiniowany jako
constexpr
auto txt = "text"sv;
- zdefiniowany w nagłówku
Obiekt
string_view
zapewnia podobną funkcjonalność jakstd::string
:operator[]
at()
data()
size()
length()
find()
find_first_of()
find_last_of()
Zapewnia operatory porównania i wyliczania skrótu (
std::hash<std::string_view>
)
Różnice między string_view a string¶
Wartość po konstrukcji domyślnej dla wewnętrznego wskaźnika to
nullptr
string::data
nie może zwrócićnullptr
string_view txt; assert(txt.data() == nullptr); assert(txt.size() == 0);
Typ
string_view
nie ma gwarancji, że bufor znaków jest zakończony zerem (null terminated string)char txt[3] = { 't', 'x', 't' }; string_view txt_v(txt, sizeof(txt)); // this view is not null terminated
Ostrzeżenie
Dla string_view
zawsze należy sprawdzić rozmiar operacją size()
zanim użyty zostanie operator[]
lub wywołana zostanie metoda data()
Konwersje string <->
string_view¶
- Konwersja
string -> string_view
jest szybka- dozwolona niejawna konwersja przy pomocy
std::string::operator string_view()
- dozwolona niejawna konwersja przy pomocy
- Konwersja
string_view -> string
jest kosztowna- wymagana jawna konwersja -
explicit std::string::string(string_view sv)
- wymagana jawna konwersja -
Użycie string_view w API funkcji¶
- Obiekty
string_view
przekazywane jako argumenty wywołania funkcji powinny być przekazywane przez wartość.
void foo_s(const string& s);
void foo_sv(string_view sv);
foo_s("text"); // computes length, allocates memory, copies characters
foo_sv("text"); // computes only length
string_view
powinno być stosowane zamiaststring
jeśli:- API nie wymaga, aby tekst był zakończony zerem
- nie można przekazywać
string_view
do funkcji języka C
- nie można przekazywać
- odbiorca respektuje czas życia obiektu
- dostęp do danych przy pomocy metody
data()
uwzględnia potencjalny pusty wskaźnik (nullptr
)
- API nie wymaga, aby tekst był zakończony zerem
Należy unikać zwracania
string_view
, chyba że jest to świadomy wybór programistyzwrócenie
string_view
może być niebezpieczne - należy pamiętać o tym, żestring_view
jest non-owning viewstring_view start_from_word(string_view text, string_view word) { return text.substr(text.find(word)); }
Jeśli wywołamy funkcję
start_from_word()
w następujący sposób:auto text = "one two three"s; auto sv = start_from_word(text + " four", "two");
Dostaniemy instancję
string_view
z wiszącym wskaźnikiem odnoszącym się do nieaktualnej już tablicy znaków, która została zwolniona w momencie wyjścia z funkcji.
Dostarczanie obydwu wersji funkcji jako przeciążeń może powodować dwuznaczności:
void foo(const string& s); void foo(string_view sv); foo("ambigous"); // ERROR - ambigous call