string_view
std::string_view 是 C++17 引入的"字符串视图",本质上是一个指针 + 长度,对一段已有的字符序列提供只读视图。它不拥有数据,因此拷贝极轻量,且不触发任何内存分配。
核心价值:函数参数用 string_view 代替 const std::string&,可以同时接受 std::string、C 字符串字面量、char*,且零拷贝。
头文件与基本特征
#include <string_view>
| 特征 | 说明 |
|---|---|
| 所有权 | 不拥有底层数据 |
| 构造 | 可从 std::string、const 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) |
使用注意
string_view只是"借用"数据,必须确保底层数据在视图使用期间有效。- 不要返回局部
std::string的string_view——它会悬空。 data()不保证以\0结尾,传给 C API 时需注意。- 如果函数需要持有一份数据,用
std::string而不是string_view。
小结
std::string_view 是 C++17 中最实用的新增类型之一。只要函数只需要"读取字符串内容"而不需要拥有,就把参数写成 string_view——性能无损、接口更通用。