std::String_view 生命周期完全依赖原始数据,不拥有数据;一旦源被销毁,view即悬垂,访问将导致未定义行为,故不可返回局部字符串的view,应优先用const std::string&传参或确保源为静态存储期。

std::string_view 的生命周期完全依赖于它所指向的原始数据
它不拥有数据,只是轻量级视图。一旦原始 std::string、C 风格字符串字面量或栈上数组被销毁或移动,std::string_view 立即变成悬垂(dangling),访问其 data() 或调用 operator[] 会触发未定义行为。
避免在函数返回值中直接返回局部 string_view
这是最常见也最危险的误用。局部 std::string 构造后立即转成 std::string_view 并返回,等函数退出,局部字符串析构,view 指向已释放内存。
std::string_view bad_example() { std::string s = "hello"; return std::string_view{s}; // ❌ 悬垂:s 在函数末尾销毁 }
- 正确做法:返回
std::string(有所有权)或确保源数据生命周期长于 view - 若必须返回 view,只对静态存储期数据安全,例如:
return std::string_view{"literal"};(字面量生命周期为整个程序) - 不要对
std::to_string(...)、s.substr(...)等临时对象取 view 后返回
传参时优先用 const std::string&,而非 std::string_view,除非明确需要跨字符串类型兼容
std::string_view 作为参数确实能避免隐式构造 std::string,但代价是把生命周期责任完全推给调用方。而 const std::string& 虽多一次隐式转换开销(对字面量或 char*),但语义更安全、意图更清晰。
- 用
std::string_view参数的合理场景:函数需同时接受std::string、C 字符串、std::Array等多种底层数据,且你**完全信任调用方管理好源数据生命周期** - 如果函数内部可能存储该 view(如缓存、成员变量),绝对禁止 —— 必须复制为
std::string - 编译器无法检查 view 是否悬垂,静态分析工具(如 clang-tidy 的
cppcoreguidelines-pro-bounds-array-to-pointer-decay)也难以覆盖所有情况
注意 std::string_view 构造时的隐式截断与空终止假设
构造 std::string_view 时不检查 NULL 字符,也不保证以