Abseil之string_view
本文翻译下面网址
https://abseil.io/tips/1
什么是string_view,你需要关心什么?
当创建一个以(常量)字符串为参数的函数时,您有四种选择:两种是您已经知道的,两种是您可能不知道的:
void TakesCharStar(const char* s); // C convention
void TakesString(const string& s); // Old Standard C++ convention
void TakesStringView(absl::string_view s); // Abseil C++ convention
void TakesStringView(std::string_view s); // C++17 C++ convention
前两种情况在调用者使用已经提供的格式的字符串时效果最好。是在需要转换(从const char*转换为string或从string转换为const char*)时会发生什么?
调用者需要将string转换为const char* 需要使用(高效但不方便)c_str()函数:
void AlreadyHasString(const string& s) {TakesCharStar(s.c_str()); // explicit conversion
}
调用者需要将const char*转换为string,不需要执行任何其他操作(好消息),但会调用创建(方便但效率低下)临时字符串,复制该字符串的内容(坏消息):
void AlreadyHasCharStar(const char* s) {TakesString(s); // compiler will make a copy
}
那怎么办呢?
谷歌接受这些字符串参数的首选方法是通过一个string_view
。这是一个“预先采用的”C++ 17的类型——在C++ 17中构建你应该使用std::string_view
,在任何不能依赖C++ 17的代码中,你应该使用absl::string_view
。
string_view
类的一个实例可以看作是进入现有字符缓冲区的“视图”。具体来说,一个string_view
只包含一个指针和一个长度,用于标识字符串视图不拥有且不能被该视图修改的字符数据部分。因此,复制一个string_view
是一个简单的操作:不复制任何字符串数据。
string_view具有来自const char*和const string&的隐式转换构造函数,而且由于string_view不进行复制,因此对于生成隐藏的复制没有O(n)内存惩罚。在传递const string&
的情况下,构造函数在O(1)时间内运行。在传递const char*的情况下,构造函数会自动调用strlen()(或者可以使用双参数字符串_View构造函数)。
void AlreadyHasString(const string& s) {TakesStringView(s); // no explicit conversion; convenient!
}void AlreadyHasCharStar(const char* s) {TakesStringView(s); // no copy; efficient!
}
因为string_view
不拥有其数据,所以string_view
指向的任何字符串(就像const char*)都必须具有已知的寿命,并且必须比string_view
本身的寿命长。这意味着使用string_view
进行存储通常是有问题的:您需要一些证据证明基础数据将比string_view
寿命更长。
如果您的API只需要在单个调用期间引用字符串数据,而不需要修改数据,那么接受字符串视图就足够了。如果以后需要引用数据或需要修改数据,则可以使用字符串(string(my_string_view))
将其显式转换为C++字符串对象。
将string_view
添加到现有的代码库中并不总是正确的答案:将参数更改为string_view
,然后将这些参数传递给需要string
或以nul结尾的const char*的函数,则效率可能很低。最好采用从实用程序代码开始向上工作的string_view
,或者在启动新项目时完全一致。
一些附加说明:
与其他字符串类型不同,您应该像传递int或double那样按值传递string_view,因为string_view是一个小值。
string_view
不一定以nul结尾。因此,下面的写法是不安全的:
printf("%s\n", sv.data()); // DON’T DO THIS
但是,以下是可以的:
printf("%.*s\n", static_cast<int>(sv.size()), sv.data());
可以像输出string或者常量char*一样输出string_view
:
std::cout << "Took '" << s << "'";
在大多数情况下,您可以将接受const string& 或者 NUL-terminated的const char*的现有例程安全地转换为string_view。执行此操作时遇到的唯一危险是,如果函数的地址被占用,这将导致生成中断,因为生成的函数指针类型将不同。
Abseil之string_view相关推荐
- string_View理解与用法(一)
什么是string_view 当你创建一个将(常量)字符串作为参数的函数时,你有四个选择,你可能知道两个,但不知道另外两个: void TakesCharStar(const char* s); // ...
- Abseil系列一:简介
关于 Abseil 由 Google 的基础 C ++ 和 Python 代码库组成,包括一些正支撑着如 gRPC.Protobuf 和 TensorFlow 等开源项目并一起 "成长&qu ...
- string_view理解与用法(二)
以前写了<string_View理解与用法(一)>和<详解C++17下的string_view>,请参考. 本篇文章从string_view引入的背景出发,依次介绍了其相关的知 ...
- 详解C++17下的string_view
看到一个介绍 C++17 的系列博文(原文),有十来篇的样子,觉得挺好,看看有时间能不能都简单翻译一下,这是第五篇~ 当字符串数据的所有权已经确定(譬如由某个string对象持有),并且你只想访问(而 ...
- C++17新特性之std::string_view
std::string_view系C++17标准发布后新增的内容,类成员变量包含两个部分:字符串指针和字符串长度,相比std::string, std::string_view涵盖了std::stri ...
- c++ string substr_用std::string_view替换leveldb的Slice
C++17中加入的std::string_view类,在用const char*类型的数据来传参时可以减少不必要的内存分配. void f1(const string& str) { -- } ...
- Abseil之New Join API
你们中的许多人要求新的加入API,我们听到了.我们现在有一个连接函数来替换它们,它的拼写是absl::StrJoin().只需给它一个要联接的对象集合和一个分隔符字符串,其余的就可以了.它将与std: ...
- Abseil之拆分字符串
在任何通用编程语言中,将字符串分割成子串是一个常见的任务,C++也不例外.当谷歌出现需求时,许多工程师发现自己正艰难地通过一个不断增长的头文件分割函数的泥潭.您可能已经找到了满足您需求的输入参数.输出 ...
- Abseil之字符串连接
当代码reviower人说:"不要使用字符串连接操作符,它不是那么高效"时,用户常常感到惊讶.std::string::operator+不高效?搞错了吧? 事实证明,这样的低效率 ...
最新文章
- centos7防火墙开放端口
- 《大数据》第1期“论坛”——对大数据国家战略的几点考虑
- Js中fetch方法
- linux目录 31:1,Linux常用基础命令
- 国产Linux二十年揭秘
- 谷歌浏览器打开特殊端口号地址方法
- 腾讯云服务器安装redis、mysql
- 服务器版系统和w7区别,小编告诉大家W7精简版和旗舰版啥区别
- M1芯片MacBook安装手机app
- php 前端 java培训哪个好,php培训、前端培训、java培训哪个好
- rdkitnlp | smiles数据扩增与smiles标准化
- C语言课题1:猜数字游戏【从基础开始手把手教你】
- java支付宝网站支付
- Kaggle泰坦尼克号船难--逻辑回归预测生存率
- 虚拟机安装Win10纯净版操作系统
- Faster R-CNN文章翻译——中英文对照
- 改变边框线条与背景重叠的布局
- Ka的分治|归并排序,注释详尽
- 滑动条做调色板cv2.getTrackbarPos()和cv2.creatTrackbar()
- Redis | 第6章 事件与客户端《Redis设计与实现》