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 结尾