string_view 提供字符串的一个视图。使用 string_view 能够减少字符串的拷贝。

  • basic_string_view : 模板类
  • std::string_view : std::basic_string_view<char>
  • std::wstring_view : std::basic_string_view<wchar_t>
  • std::u8string_view : std::basic_string_view<char8_t>
  • std::u16string_view : std::basic_string_view<char16_t>
  • std::u32string_view : std::basic_string_view<char32_t>

可用标准库函数

  • std::begin()
  • std::end()
  • std::cbegin()
  • std::cend()
  • std::rbegin()
  • std::rend()
  • std::crbegin()
  • std::crend()
  • std::size()
  • std::ssize()
  • std::empty()
  • std::data()
#include <iostream>
#include <string_view>

int main() {
std::string_view str {"hello world"};
for (auto it = std::begin(str); it != std::end(str); ++it) {
std::cout << *it << " "; // h e l l o w o r l d
}
std::cout << '\n';

for (auto it = std::cbegin(str); it != std::cend(str); ++it) {
std::cout << *it << " "; // h e l l o w o r l d
}
std::cout << '\n';

for (auto it = std::rbegin(str); it != std::rend(str); ++it) {
std::cout << *it << " "; // d l r o w o l l e h
}
std::cout << '\n';

for (auto it = std::crbegin(str); it != std::crend(str); ++it) {
std::cout << *it << " "; // d l r o w o l l e h
}
std::cout << '\n';

std::cout << std::size(str) << '\n'; // 11
// std::cout << std::ssize(str) << '\n'; // for c++ 20, get sign size
std::cout << std::boolalpha << std::empty(str) << '\n'; // false
std::cout << std::data(str) << '\n'; // hello world
return 0;
}

basic_string_view 模板类

basic_string_view 和其他容器类一样,拥有一些类型成员

  • traits_type : Traits
  • value_type : charT
  • pointer : charT*
  • const_pointer : const charT*
  • reference : charT&
  • const_reference : const charT&
  • iterator
  • const_iterator
  • reverse_iterator
  • const_reverse_iterator
  • size_type : std::size_t
  • difference_type : std::ptrdiff_t

basic_string_view 中的迭代器函数

  • begin()
  • end()
  • cbegin()
  • cend()
  • rbegin()
  • rend()
  • crbegin()
  • crend()
#include <iostream>
#include <string_view>

int main() {
std::string_view str {"hello world"};
for (auto it = str.begin(); it != str.end(); ++it) {
std::cout << *it << " "; // h e l l o w o r l d
}
std::cout << '\n';

for (auto it = str.cbegin(); it != str.cend(); ++it) {
std::cout << *it << " "; // h e l l o w o r l d
}
std::cout << '\n';

for (auto it = str.rbegin(); it != str.rend(); ++it) {
std::cout << *it << " "; // d l r o w o l l e h
}
std::cout << '\n';

for (auto it = str.crbegin(); it != str.crend(); ++it) {
std::cout << *it << " "; // d l r o w o l l e h
}
std::cout << '\n';
return 0;
}

basic_string_view 中的获取函数和容量函数

  • operator[] : 获取索引对应的元素,当索引超出范围后为未定义行为,会报错
  • at : 获取指定元素,会进行范围检查
  • front : 获取第一个字符
  • back : 获取最后一个字符
  • data : 返回指向第一个字符的 view 指针
  • size : 返回 view 中字符的数量
  • length : 返回 view 中字符的数量
  • max_size : 返回字符的最大数量
  • empty : 检查 view 是否为空
#include <iostream>
#include <string_view>

int main() {
std::string_view str {"hello world"};
std::cout << str[4] << '\n'; // o
// std::cout << str[13] << '\n'; // error: undefined behavior, do not throw
std::cout << str.at(4) << '\n'; // o
try {
std::cout << str.at(13) << '\n';
}
catch (const std::out_of_range& e) {
std::cout << "index 13 out of range" << '\n'; // index 13 out of range
std::cout << e.what() << '\n'; // invalid string_view position
}
std::cout << str.front() << '\n'; // h
std::cout << str.back() << '\n'; // d
std::cout << str.data() << '\n'; // hello world
std::cout << str.size() << '\n'; // 11
std::cout << str.length() << '\n'; // 11
std::cout << str.max_size() << '\n'; // 2147483647 (2^31 - 1)
std::cout << std::boolalpha << str.empty() << '\n'; // false
return 0;
}

basic_string_view 中的修改函数和操作函数

  • remove_prefix : 删除前 n 个字符
  • remove_suffix : 删除后 n 个字符
  • swap : 交换内容
  • copy : 拷贝字符
  • substr : 返回子串 view
  • compare : 比较两个 views
  • starts_with : 检查是否以指定前缀开始
  • ends_with : 检查是否以指定后缀结束
  • find : 查找
  • rfind : 反向查找
  • find_first_of : 查找第一个符合条件的字符
  • find_last_of : 查找最后一个符合条件的字符
  • find_first_not_of : 查找第一个不符合条件的字符
  • find_last_not_of : 查找最后一个不符合条件的字符
  • std::string_view::npos :
  • operator""sv : string view literals
#include <iostream>
#include <string_view>

int main() {
std::string_view str {" hello world++++"};
str.remove_prefix(str.find_first_not_of(' '));
std::cout << str << '\n'; // hello world++++
str.remove_suffix(str.size() - str.find_last_not_of('+') - 1);
std::cout << str << '\n'; // hello world

std::string_view strView1 {"I Love C++"};
strView1.swap(str);
std::cout << str << '\n'; // I Love C++
std::cout << strView1 << '\n'; // hello world

std::cout << str.substr(2, 4) << '\n'; // Love
// std::cout << std::boolalpha << str.starts_with("I") << '\n'; // for C++ 20
// std::cout << std::boolalpha << str.ends_with("C++") <<'\n'; // for C++ 20
std::cout << str.find('L') << '\n'; // 2
std::cout << str.find("Love") << '\n'; // 2
std::cout << str.rfind('+') << '\n'; // 9
std::cout << str.find_first_of('+') << '\n'; // 8
std::cout << str.find_last_of('+') << '\n'; // 9
std::cout << std::boolalpha << (str.find("like") == std::string_view::npos) << '\n'; // true
std::cout << "hello world"sv.size() << '\n'; // 11
std::cout << strView1.compare("hello world"sv) << '\n'; // 0
return 0;
}