文档目录

解决什么问题?

// ❌ 问题:把字符串切一段出来,就要分配内存
std::string full = "user:warren:logged_in";
std::string name = full.substr(5, 6);  // "warren" → 分配堆内存!

// ✅ string_view:只记录指针和长度,不拷贝
std::string_view full_sv = full;
std::string_view name_sv = full_sv.substr(5, 6);  // "warren" → 不分配!
// name_sv.ptr 指向 full 内部第 6 个字符的位置

什么时候用?

场景 用 string_view
函数参数,只读字符串 void parse(std::string_view input)——接受 string、char*、string_view 而不拷贝
子串提取,不需要修改 sv.substr(pos, len) 不分配内存
快速比较前缀/后缀 sv.starts_with("http") sv.ends_with(".png")
日志/消息解析 从大字符串中切出各字段而不拷贝

致命陷阱:生命周期

std::string_view get_name() {
    std::string temp = "temporary";
    return temp;  // ✅ 赋值时 temp 还活着
}  // ❌ temp 析构,sv 悬垂!

auto sv = get_name();
std::cout << sv;  // 💥 Use-After-Free!可能打印出乱码或 crash

规则:string_view 不拥有数据。你必须保证原始字符串活到 string_view 用完。

函数参数的最佳实践

// ❌ 不好:只接受 string,传 char* 会隐式构造 string(分配内存)
void parse(const std::string& s);

// ✅ 好:接受 string_view,字符串字面量/char*/string 都行,不拷贝
void parse(std::string_view sv);

parse("hello");           // char* → 不拷贝
parse(std::string("x"));  // string → .data()+size 被 view 借用
parse(some_view);         // view → 直接复制指针+长度