cstring转换为string_Tip of the Week #1: string_view

Tip of the Week #1: string_view

Originally published as totw/1 on 2012-04-20By Michael Chastain (mec.desktop@gmail.com)Updated 2017-09-18

什么是 string_view, 我们为什么要关心它?

当我们创建一个函数并且这个函数有一个参数是用来接收常量字符串的,这时你有四个选择,其中有两个是你已经知道的,另外两个你或许还不知道:

e7418d34d622f539a1f763a43acd3708.png

前两种方式最适合那种调用者提供参数和行参的类型是一致的,但是如果不一致是否需要进行转换(可能是 constchar*转换为 string或者是 sgtring转换为 constchar*)?

调用者需要将 string转换为 constchar*是需要使用(高效但是不方便) c_str()函数:

e81186ffd8cd765ec1bd820d7196e8a3.png

调用者需要将一个 constchar*转换为一个 string的时候是不需要做任何额外事情的(这是一个好消息),但是这会导致编译器会隐式的创建一个临时的字符串(方便但是不高效),然后将 constchar*中的内容拷贝到这个 string中(这是个不好的消息):

1903366a13b54e7c0ddd0aee11fe982a.png

要做什么?

谷歌的首选是通过 string_view的方式来接收字符串参数,在 C++17中可以使用 std::string_view来替代,在那些还没有使用 C++17的代码中可以使用 absl::string_view来替代。

一个 string_view类的实例可以被认为是一个对现存的字符bufer的视图,具体来说 string_view仅仅包含了一个指针和一个长度,仅用来标识一段字符数据并不拥有这段数据,不能通过这个视图来修改对应的数据。所以对一个 string_view的拷贝是浅拷贝,是没有字符串数据的拷贝的。

string_view可以隐式的从一个 constchar*conststring&构造出来,并且不会造成字符串数据的拷贝产生O(n)的复杂度,例如当传递一个 conststring&的时候,构造函数仅会产生O(1)的复杂度,当传递一个 constchar*的时候构造函数会自动的调用一个 strlen函数(或者你可以传递两个参数给 string_view)。

dd28fd05fc7ad0d7857b16542e7a7245.png

因为 string_view不拥有数据,所以被 string_view所指向的字符串(类似于 constchar*)都必须有一个已知的生命周期,而且其生命周期要长于 string_view对象自己。这意味着使用 string_view来存储字符串通常是有问题的,你需要证明你引用的底层数据其生命周期要长于 string_view对象自己的。

如果你的API仅仅是需要在一个单次调用中引用一个字符串数据,而且不会修改数据,那么接收一个string_view作为参数这是足够的。如果你还需要在调用后还引用这个数据,或者修复这个数据,那么你需要显示通过 string(my_string_view)来将其转换 string类型。

string_view添加到现存的代码中并不总是正确的,如果传递给这个函数的需要的就是一个 string或者是一个 constchar*使用 string_view并不会很高效。最佳的方案是从工具代码开始向上开始采用 string_view来替换,或者是从一个新项目一开始就保持一致。

一些额外的注意事项

  • 和其他字符串类型不一样的点在于 string_view传递的时候应该按照值拷贝的方式传递,就像传递 int和 double类型一样,因为 string_view就是一个小数值。

  • string_view不需要以 NULL结尾,因此如果这样输出是不安全的:

1f94d775253c5ea08e2938806d3906c5.png

然后,下面这样是可以的:c++printf("%.*s\n",static_cast(sv.size()),sv.data());

  • 你应该像一个 string或者 constchar*那样来输出 string_view

d4107f13373fea14a804cb146ed1a378.png

  • 在大多数情况下你将安全的将一个现存的接收 conststring&或 constchar*参数的函数转换为 string_view我们在执行此操作时遇到的唯一危险是,如果函数的地址已被占用,则会导致构建中断,因为所产生的函数指针类型将有所不同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值