跳至內容

C++/string view

維基教科書,自由的教學讀本
< C++

標準模板庫頭文件 <string_view>是C++17提出的。

由於std::string_view的對象只包含2個指針(一個const char* 指針,指向數據區的開始地址;一個size_t長度,記住數據區大小),所以相當於值對象。與const std::string&相比,std::string_view避免了潛在可能的對象構造。零拷貝。例如: std::string_view v1("hello");

但需要注意,std::string_view不擁有數據。所以它觀察的那個原始字符串必須比它活得長。std::string_view不以\0結尾,data()方法返回的不要直接給 printf、fopen這些指望\0的C函數。

string_view沒有隱式轉換成 std::string 的能力。這是故意的,防止無意間觸發堆分配,需要明明白白地寫 std::string(sv) 。

必要性

[編輯]

即使使用void foo(const std::string& str)方式,如果實參是字符串字面量 "hello",實參類型是const char*,編譯器會隱式new了一個臨時std::string對象,把"hello"構造進去,函數調用返回後再析構掉。

子串操作上,開銷尤其明顯,例如:

std::string extract_fields(const std::string& s) 
{
    return s.substr(0, 5); // 返回的是新 string,又一次堆分配 + 拷贝
}

如果在一個循環里做解析,如處理幾萬行日誌,substr每調一次就構造一次std::string。

類模板basic_string_view

[編輯]

只讀的字符串視圖。string_view的成員函數即對外接口與 string 相類似(但區別在於是否以\0結尾),但只包含讀取字符串內容的部分。

  • string_view::substr()的返回值類型是string_view,不產生新的字符串,不會進行內存分配。
  • string::substr()的返回值類型是string,產生新的字符串,會進行內存分配。
  • string_view字面量的後綴是 sv(C++17支持sv;string字面量的後綴是 s)可處理包含\0的字符串。自適應各種CHAR_T
  • std::string_view std::basic_string_view<char>
  • std::u8string_view std::basic_string_view<char8_t> (C++20)
  • std::u16string_view std::basic_string_view<char16_t>
  • std::u32string_view std::basic_string_view<char32_t>
  • std::wstring_view std::basic_string_view<wchar_t>
  • std::hash<std::string_view> string_view 的散列支持
  • std::hash<std::wstring_view>
  • std::hash<std::u8string_view>
  • std::hash<std::u16string_view>
  • std::hash<std::u32string_view>


函數 以字典序比較兩個字符串視圖

  • operator==
  • operator!=
  • operator<
  • operator>
  • operator<=
  • operator>=
  • operator<=> (C++20)

函數模板

  • operator<< 進行字符串視圖的流輸出
  • size
  • length
  • max_size 可包含的字符的最多數量
  • empty
  • operator[]
  • at
  • front
  • back
  • remove_prefix 參數為被刪掉的字符個數
  • remove_suffix 參數為被刪掉的字符個數
  • swap
  • copy
  • substr
  • compare
  • starts_with
  • ends_with
  • contains
  • find
  • rfind
  • find_first_of
  • find_last_of
  • find_first_not_of
  • find_last_not_of
  • data // 返回 const char*,但不以 \0 結尾