Skip to main content
Version: Next

string_view

std::string_view 是 C++17 引入的"字符串视图",本质上是一个指针 + 长度,对一段已有的字符序列提供只读视图。它不拥有数据,因此拷贝极轻量,且不触发任何内存分配。

核心价值:函数参数用 string_view 代替 const std::string&,可以同时接受 std::string、C 字符串字面量、char*,且零拷贝。

头文件与基本特征

#include <string_view>
特征说明
所有权不拥有底层数据
构造可从 std::stringconst char*、字符数组构造
修改只读,不提供修改接口
零拷贝拷贝 string_view 只拷贝指针和长度
非空终止不保证 \0 结尾

基本用法

#include <iostream>
#include <string>
#include <string_view>

void print(std::string_view sv) {
std::cout << "[" << sv << "] size=" << sv.size() << '\n';
}

int main() {
print("hello"); // C 字符串
print(std::string("world")); // std::string 隐式转换
std::string s = "hi";
print(std::string_view(s)); // 显式构造

return 0;
}

子串——零拷贝切片

substr()string_view 上是 O(1),不复制数据:

std::string_view sv = "hello world";
std::string_view part = sv.substr(0, 5); // "hello",零拷贝

std::string::substr() 会分配新内存。这是 string_view 最大的性能优势。

常用接口

接口作用
size() / length()字符数
substr(pos, n)子串视图(O(1)
find(x) / rfind(x)查找字符/子串
find_first_of(x) / find_last_of(x)找字符集中任一字符
starts_with() / ends_with()C++20 才支持
remove_prefix(n)从头部缩去 n 个字符
remove_suffix(n)从尾部缩去 n 个字符
data()获取底层指针(不保证 \0

使用注意

  1. string_view 只是"借用"数据,必须确保底层数据在视图使用期间有效。
  2. 不要返回局部 std::stringstring_view——它会悬空。
  3. data() 不保证以 \0 结尾,传给 C API 时需注意。
  4. 如果函数需要持有一份数据,用 std::string 而不是 string_view

小结

std::string_view 是 C++17 中最实用的新增类型之一。只要函数只需要"读取字符串内容"而不需要拥有,就把参数写成 string_view——性能无损、接口更通用。