C++ 17 std::string_view

C++ 17 std::string_view

std::string_view 可以理解成“对一段字符串的只读视图”。它本身不拥有字符串数据,只是记录一段字符范围,因此非常轻量。

1. 为什么需要 string_view?

以前函数参数常见写法一般是:

  • const std::string&
  • const char*

这两种都能用,但各有问题:

  • const std::string& 对字符串字面量不够灵活
  • const char* 只看指针不看长度

std::string_view 则正好补上了“只读、不拷贝、带长度”的这一层。

2. 基本使用

1
2
3
4
5
6
7
8
9
10
11
#include <string_view>
#include <iostream>
using namespace std;

int main()
{
string_view sv = "hello world";
cout << sv << endl;
cout << sv.size() << endl;
return 0;
}

3. 它不会拷贝字符串

这是它最大的特点之一:

1
2
3
4
void print(std::string_view sv)
{
std::cout << sv << std::endl;
}

调用时无论传:

  • std::string
  • 字符串字面量
  • 部分字符区间

通常都很方便,而且不需要新分配内存。

4. 常见操作

4.1 截取前缀后缀

1
2
3
string_view sv = "abcdef";
sv.remove_prefix(2); // cdef
sv.remove_suffix(1); // cde

4.2 子串

1
auto sub = sv.substr(1, 3);

4.3 比较

1
2
if (sv == "abc") {
}

5. 一个很常见的参数场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <string>
#include <string_view>
#include <iostream>
using namespace std;

void logText(string_view text)
{
cout << text << endl;
}

int main()
{
string s = "hello";
logText(s);
logText("world");
return 0;
}

这类接口如果写成 string_view,通常会比 const std::string& 更灵活。

6. 使用时最重要的注意点

6.1 它不拥有数据

这意味着:

1
2
3
4
5
std::string_view sv;
{
std::string s = "hello";
sv = s;
}

离开作用域后,sv 仍然指向原来的内存位置,但那块数据已经失效了。
这就是 string_view 最容易踩的坑。

6.2 适合只读,不适合修改

它本来就是视图,不负责改内容。

6.3 生命周期必须比 view 长

记住这一点,基本就能避免大部分问题。

总结

std::string_viewC++17 里非常常用的一个类型。
它轻量、只读、不拷贝,很适合做函数参数和字符串切片处理。唯一要特别小心的就是生命周期问题,因为它只是“看着字符串”,并不拥有字符串。