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_viewstring_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_tstd::u16string_view- dla typuchar16_tstd::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_viewzapewnia 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
nullptrstring::datanie może zwrócićnullptr
string_view txt; assert(txt.data() == nullptr); assert(txt.size() == 0);
Typ
string_viewnie 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_viewjest szybka- dozwolona niejawna konwersja przy pomocy
std::string::operator string_view()
- dozwolona niejawna konwersja przy pomocy
- Konwersja
string_view -> stringjest kosztowna- wymagana jawna konwersja -
explicit std::string::string(string_view sv)
- wymagana jawna konwersja -
Użycie string_view w API funkcji¶
- Obiekty
string_viewprzekazywane 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_viewpowinno być stosowane zamiaststringjeśli:- API nie wymaga, aby tekst był zakończony zerem
- nie można przekazywać
string_viewdo 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_viewmoże być niebezpieczne - należy pamiętać o tym, żestring_viewjest 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_viewz 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