Cpp17-std::string_view用法

Cpp17-std::string_view

std::string_view用法

C++ 中有两种风格的字符串,分别是C风格的字符串、std::string字符串。C风格的字符串性能更高,但是叶不方便使用。如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main()
{
//C风格字符串总是以null结尾
char cstr1[] = { 'j', 'a', 'm', NULL};
char cstr2[4];
strcpy(cstr1, cstr2);
std::cout << cstr2 << std::endl;

//C++风格的字符串操作更方便,但是性能不如C风格字符串
std::string str = "jam";
std::string str2 = str;
}

C++17中我们可以使用std::string_view来获取一个字符串的视图,字符串视图并不真正的创建或者拷贝字符串,而只是拥有一个字符串的查看功能。std::string_view比std::string的性能要高很多,因为每个std::string都独自拥有一份字符串的拷贝,而std::string_view只是记录了自己对应的字符串的指针和偏移位置。当我们在只是查看字符串的函数中可以直接使用std::string_view来代替std::string。

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

int main()
{

const char* cstr = "jam";
std::string_view stringView1(cstr);
std::string_view stringView2(cstr, 2);
std::cout << "stringView1: " << stringView1 << ", stringView2: " << stringView2 << std::endl;

std::string str = "jam";
std::string_view stringView3(str.c_str());
std::string_view stringView4(str.c_str(), 2);
std::cout << "stringView3: " << stringView3 << ", stringView4: " << stringView4 << std::endl;
}

输出:

1
2
stringView1: jam, stringView2: ja
stringView3: jam, stringView4: ja

我们可以把原始的字符串当作一条马路,而我们是在马路边的一个房子里,我们只能通过房间的窗户来观察外面的马路。这个房子就是std::string_view,你只能看到马路上的车和行人,但是你无法去修改他们,可以理解你对这个马路是只读的。正是这样std::string_view比std::string会快上很多。

std::string_view容易踩坑的点

在Effective C++和C++ primer中都提到过,当一个函数有 std::string 类型的参数,如果这个参数它不会被修改,那么应该以 const-reference 的方式传递。即使用const string &str而不是string str

而上面说过,使用std::string会有性能问题,因为当我们一个函数的参数为const string& str时,如果传进来的参数是一个C风格的字符串,那么编译器会自动的创建一个std::string对象,编译器会使用这个C风格的字符串构造一个std::string,这样就会多一份std::string的构造开销。而如果我们使用std::string_view,那么就不会有这个问题,因为std::string_view只是一个指针,不会拷贝字符串。

但是我们要注意,std::string_view并不是一个完全的替代std::string的类型,因为std::string_view只是一个引用,它并不拥有字符串,所以当我们使用std::string_view时,我们必须保证这个字符串的生命周期要比std::string_view的生命周期要长。

attention

在使用std::string_view作为函数参数的时候,最好不要使用引用传参,因为std::string_view的本质就是一个引用,使用引用的引用并不会带来更多好处。

参考:


Cpp17-std::string_view用法
https://gstarmin.github.io/2023/07/17/Cpp17-std-string-view用法/
作者
Starmin
发布于
2023年7月17日
许可协议