c++ string长度_C/C++编程日记:Tip string_view

这个tip的背景是,将字符串作为函数参数进行传递

常规方法

858472c4607381b4667b69070acb0d19.png

将字符串作为函数参数进行传递,容易想到的是以下两个方法:

voidTakesCharStar(constchar* s);// C

voidTakesString(conststring& s);// Old Standard C++

这两种方法只能接收确定类型的字符串作为参数,否则可能需要类型转换。比如下面这两个场景:

一、使用c_str()函数将string类型显式转换为const char*:

voidAlreadyHasString(conststring& s){

TakesCharStar(s.c_str());// 显式类型转换

}

二、对于void TakesString(const string& s),即第二个方法,如果我们已有的数据是const char*类型,这时虽然不需要显式地进行类型转换,但是编译器会执行拷贝操作来创建一个临时的string

voidAlreadyHasCharStar(constchar* s){

TakesString(s);// compiler will make a copy

}

应该怎么办?

谷歌建议利用string_view来传递字符串参数。

828565373b459fc2a23fd5931f288496.png

需要注意的是,std::string_view到C++17标准才支持,否则的话你可以用absl::string_view

voidTakesStringView(absl::string_view s);// Abseil C++

voidTakesStringView(std::string_view s);// C++17 C++

string_view可以看成是一个字符串缓存的view,它只保留着这块内存的地址和长度,也因此无法通过string_view来修改字符串的内容,拷贝时也无需对实际的字符串数据进行拷贝。

从const char*和const string&到string_view的类型转换是隐式的,而且过程中也不会发生数据的拷贝。所以我们可以认为string_view的构造时间复杂度是O(1)的。

voidAlreadyHasString(conststring& s){

TakesStringView(s);// 没有显式的类型转换

}

voidAlreadyHasCharStar(constchar* s){

TakesStringView(s);// 没有拷贝

}

由于string_view不拥有实际的数据,而只是保存一个指向实际数据的指针,所以在使用string_view时我们需要保证:字符串实际数据的生命周期要长于string_view。

0ba783b3baab2c77c0826ec7f0522ab3.gif

如果你的API只在一次调用中需要使用这个字符串,而且不需要修改其中的内容,此时使用string_view不需要有任何顾虑。如果后面还要使用这个字符串,或者需要修改其中内容,可以使用string(my_string_view)进行显式的类型转换。

44703a0b8fd9cdcd0f7b129e82e59f3b.png

在现在的项目中使用string_view可能不会是一个明智的选择,尤其是当一个字符串在后续使用中确定需要string或者const char*类型。所以,如果想使用string_view,最好是在上游代码中,或者是全新开始的新项目中。

注意

传递string_view可以大胆按值传递,因为其本身非常小

string_view不保证NUL-terminated,所以下面这种写法不安全

printf("%s", sv.data());// DON’T DO THIS

但可以这样用:

printf("%.*s",static_cast(sv.size()), sv.data());

std::cout<

大多情况下,我们可以放心地把以const string&或const char*为参数的函数直接改写为接收string_view类型。唯一的风险在于:如果在其他地方使用了函数的地址,则将导致Build中断,因为生成的函数指针类型将不同。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值