C++ string_view

std::string_view是C++17引入的新特性,它不持有内存,无法修改它指向的字符串,也不保证其所指向的字符串是空字符结尾的(因为 string_view 可以观察一个 std::string 的中间部分)。string_view包含一个指向字符串对象的指针和对应的长度。

常用方法

  • 除了append()push_back等会修改字符串内容的方法,std::string_view拥有大部分std::string的同名方法
  • 由于无法保证其所指向的字符串是空字符结尾的,std::string_view没有c_str()方法
  • data()返回指向数据的指针,但由于std::string_view不保证该数据是空字符结尾的,因此需要注意缓冲区溢出的问题
  • substr(size_t pos, size_t size) 移动视图的起始位置,不会创建新的子串
  • remove_prefix(size_t pos)向后移动视图的起始位置,并改变大小,不会创建新的子串,相当于substr(size_t pos)
  • remove_suffix(size_t n)向前移动视图的尾部位置,并改变大小,不会创建新的子串

const std::string &的区别

  • const std::string &只能绑定 std::string对象,或者其他可以隐式转为std::string的对象
  • std::string_view可以绑定std::string、字面量字符串 const char*char[] 等任何连续的字符序列
  • const std::string &调用substr()函数时,会创建一个新的子串,而std::string_view则只会移动指针并修改大小
  • const std::string &更加安全,std::string_view则需要确保指向的字符串在使用期间是有效的

注意事项

悬垂指针

由于std::string_view只持有指向字符串的指针,因此要时刻注意悬垂指针的问题。例如当你用它指向一个右值时

1
std::string_view sv = std::string("hello"); // 危险,临时对象会立即销毁

虽然上面的代码在语法上是没问题的(在编译器看来,它只是绑定了一个std::sting对象而已),但是当你你使用sv时它已经是一个悬垂指针了。
同时要注意区分右值和字面量,例如下面的代码

1
std::string_view sv = "hello";

"hello"是个const char[6]类型,存储在静态区,程序运行期间一直存在,所以上面的代码是完全安全的。

缓冲区溢出

由于std::string_view不保证该数据是空字符结尾的,因此需要注意缓冲区溢出的问题。

例如如果你将 string_view.data() 的结果传递给需要空字符结尾字符串的C函数(如 strcpy, printf("%s", ...)),可能会导致缓冲区溢出和未定义行为。

总结:

  • 当只需要读取字符串而不修改时,std::string_view 可以避免不必要的拷贝,也更加灵活,是个不错的选择。
  • 永远确保std::string_view指向的字符串在使用期间有效。

C++ string_view
https://guts.homes/2025/08/28/cpp-string-view/
作者
guts
发布于
2025年8月28日
许可协议