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::sting对象而已),但是当你你使用sv时它已经是一个悬垂指针了。
同时要注意区分右值和字面量,例如下面的代码
1 | |
"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/