C++17新特性之std::string_view

std::string_view系C++17标准发布后新增的内容,类成员变量包含两个部分:字符串指针和字符串长度,相比std::string, std::string_view涵盖了std::string的所有只读接口。如果生成的std::string无需进行修改操作,可以把std::string转换为std::string_view,std::string_view记录了对应的字符串指针和偏移位置,无需管理内存,相对std::string拥有一份字符串拷贝,如字符串查找和拷贝,效率更高。

废话不多说,上测试代码:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <chrono>
#include <string_view>class TimerWrapper
{
private:std::string str_type_;std::chrono::high_resolution_clock::time_point start_time_;
public:TimerWrapper(const std::string& str_type) : str_type_(str_type){start_time_ = std::chrono::high_resolution_clock::now();}~TimerWrapper(){TimeCost();}void TimeCost(){auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time_);std::cout << str_type_ << ", costtime: " << ms << std::endl;}
};void TestString(const std::string& str)
{std::cout << "string: " << str << std::endl;for (int i = 0; i < 1000000; i++){std::string sub_str = str.substr(5, 10);}
}void TestStringView(const std::string_view& str_view)
{std::cout << "str_view: " << str_view << std::endl;for (int i = 0; i < 1000000; i++){std::string_view sub_str_view = str_view.substr(5, 10);}
}std::string_view PrintStringView() 
{std::string s = "How are you..";std::string_view str_view = s;return str_view;
}int main()
{std::string str = "abcdefghijklmnopqrtstuvwxyz";{TimerWrapper timer_wrapper("string");TestString(str);}{TimerWrapper timer_wrapper("stringview");std::string_view str_view = str;TestStringView(str_view);}std::string_view str_view_str = "testing string_view related..";std::string_view str_view_sub_str = str_view_str.substr(5, 10);std::cout << "str_view_sub_str: " << str_view_sub_str << "size: " << str_view_sub_str.size() << std::endl;std::cout << "str_view_str : " << str_view_str.data() << "size: " << str_view_str.size() << std::endl;//std::string strview2strerr = str_view_str;	//报错,不能直接转换std::string strview2str = static_cast<std::string>(str_view_str);std::cout << "strview2str: " << strview2str << std::endl;std::cout << "PrintLocalStringView: " << PrintStringView() << std::endl;
}

先看看执行结果:

分析下代码,我们做的第一个比较是std::string和std::string_view性能:

void TestString(const std::string& str)
{std::cout << "string: " << str << std::endl;for (int i = 0; i < 1000000; i++){std::string sub_str = str.substr(5, 10);}
}void TestStringView(const std::string_view& str_view)
{std::cout << "str_view: " << str_view << std::endl;for (int i = 0; i < 1000000; i++){std::string_view sub_str_view = str_view.substr(5, 10);}
}

为方便数据比较,我们以执行1000000次为例,std::string因为操作过程中,会重新分配内存,生成一个对应的std::string副本,用时1065ms,std::string_view不持有字符串拷贝,与源字符串共享内存空间,其他是视图,避免了std::string频繁的字符串分配和拷贝操作,只用了85ms,效率显而易见。

第二个测试,我们看看string_view的substr操作:

std::string_view str_view_str = "testing string_view related..";
std::string_view str_view_sub_str = str_view_str.substr(5, 10);
std::cout << "str_view_sub_str: " << str_view_sub_str << "size: " << str_view_sub_str.size() << std::endl;
std::cout << "str_view_str : " << str_view_str.data() << "size: " << str_view_str.size() << std::endl;

截取后的字符串和size都是没问题的,这个很容易理解,但是,当我们调用str_view_str.data()时,打印出来的是全字符串。这个是因为str_view_str还是指向的str_view_str,调用str_view_str.data()时,直至遇到结束符\0打印才结束,所以输出的是整个源字符串。

此外,std::string的substr是线性复杂度,依赖于字符串长度, std::string_view的substr是常数复杂度,不依赖于字符串长度,std::string_view的substr的性能优于std::string的substr.

第三个问题,std::string和std::string_view转换问题,调用 string_view构造器可将std::string转换为string_view对象。std::string可隐式转换为 std::string_view,正确的转换可参考下图:

//std::string strview2strerr = str_view_str;  //报错,不能直接转换std::string strview2str = static_cast<std::string>(str_view_str);
std::cout << "strview2str: " << strview2str << std::endl;

第四个烫烫烫的问题:

std::cout << "PrintLocalStringView: " << PrintStringView() << std::endl;

由于std::string_view并不持有字符串的内存,所以它的生命周期一定要比源字符串的生命周期长,源字符串被消毁,行为未定义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌浏览器该扩展程序未列在Chrome网上应用店中解决方法

很多用户在谷歌浏览器中安装扩展程序的时候会发现有些扩展程序安装后会显示红字“该扩展程序未列在Chrome网上应用店中”&#xff0c;然后插件未能正常启用&#xff0c;这让其很是苦恼&#xff0c;那么下面就来说一下如何解决这类插件安装的问题。 谷歌浏览器该扩展程序未列在…

Android平台实现RTSP|RTMP转GB28181网关接入

背景 在事先Android平台RTSP、RTMP转GB28181网关之前&#xff0c;我们已经实现了Android平台GB28181的接入&#xff0c;可实现Android平台采集到的音视频数据&#xff0c;编码后&#xff0c;打包按需发到GB28181服务平台。此外&#xff0c;拉流端&#xff0c;我们已经有了成熟…

一句话解释C++指针和引用区别

记住一句话就够了&#xff1a;指针三心二意&#xff0c;引用从一而终&#xff01; 指针是一个实体&#xff0c;而引用可理解为一个别名&#xff1b; ”sizeof(指针)”得到的是指针本身的大小&#xff0c;”sizeof(引用)”返回所指向的变量(对象)的大小。 引用一定不为空&…

大地Win11 64位全新专业版系统V2021.08

大地Win11 64位全新专业版系统V2021.08以微软官方原版作为母盘对系统进行了全面优化更新&#xff0c;用户使用更加流畅顺手&#xff0c;轻松体验到系统的优秀性能&#xff0c;适用目前市场最新机型以及老旧机型&#xff0c;多种安装方式供用户选择&#xff0c;且更新时间短无需…

Unity3D下实现Linux平台RTMP推流(以采集Unity窗体和声音为例)

技术背景 随着物联网等行业的崛起&#xff0c;越来越多的传统行业如虚拟仿真、航天工业、工业仿真、城市规划等&#xff0c;对Linux下的生态构建&#xff0c;有了更大的期望&#xff0c;Linux平台下&#xff0c;可选的直播推拉流解决方案相对Windows和移动端&#xff0c;非常少…

电脑公司Win11 64位全新旗舰版镜像V2021.08

电脑公司Win11 64位全新旗舰版镜像V2021.08以微软官方原版作为母盘对系统进行了全面优化更新&#xff0c;用户使用更加流畅顺手&#xff0c;轻松体验到系统的优秀性能&#xff0c;适用目前市场最新机型以及老旧机型&#xff0c;多种安装方式供用户选择&#xff0c;且更新时间短…

Android平台实现VR头显Unity下音视频数据RTMP推送

背景 随着技术发展的日新月异&#xff0c;虚拟现实产业已经从过去的探索期&#xff0c;自2020年起&#xff0c;慢慢过渡到高速发展期&#xff0c;随着5G时代的到来&#xff0c;大带宽高可靠低延迟网络环境&#xff0c;为虚拟现实产业提供了很好的网络保障&#xff0c;虚拟现实…

如何快速区分C++左值和右值

C左值和右值&#xff0c;初学者经常傻傻分不清&#xff0c;可参看“C Primer”书中的描述&#xff0c;简单来说&#xff1a; 当一个对象被用作右值的时候&#xff0c;用的是对象的值&#xff08;内容&#xff09;&#xff1b;当对象被用作左值的时候&#xff0c;用的是对象的身…

Win11将沿用Win10升级模式 并会有LTSC版本

微软官方已经确认 Windows 11 将沿用 Windows 10 的升级模式&#xff0c;包括每月的安全更新、可选累积更新、紧急的带外更新、服务栈更新等等。此外&#xff0c;微软还确认将会有个长期服务渠道&#xff08;LTSC&#xff09;版本的 Windows 11。 在近日更新的官方支持文档中&…

C++11特性之std:call_once介绍

std:call_once是C11引入的新特性&#xff0c;如需使用&#xff0c;只需要#include <mutex>即可&#xff0c;简单来说std:call_once的作用&#xff0c;确保函数或代码片段在多线程环境下&#xff0c;只需要执行一次&#xff0c;常用的场景如Init()操作或一些系统参数的获取…

2022年了,该学C++还是Java?

最近好多朋友私信我&#xff0c;C好不好学&#xff1f;学C好还是Java好&#xff1f; 我的回答是&#xff1a;C不好学&#xff0c;但你觉得C不好学的话&#xff0c;Java也不好学。因为C难是难在语言本身&#xff0c;java难是难在各种框架和库。 C学习进阶比较陡, 对新手不友好&…

Outlook怎么打印日历 Outlook日历打印教程

Outlook中的日历想要打印出来&#xff0c;该怎么打印日历呢?下面我们就来看看详细的教程。 Outlook怎么打印日历? Outlook日历打印教程 1、下载安装outlook软件。 Outlook怎么打印日历? Outlook日历打印教程 2、双击打开outlook软件&#xff0c;登入邮箱账户。 Outlook…

Android平台音视频RTMP推送|GB28181对接之动态水印设计

技术背景 随着移动单兵、智能车载、智慧安防、智能家居、工业仿真、GB28281技术对接等行业的发展&#xff0c;现场已经不再限于采集到视频数据编码打包发送或对接到流媒体服务端&#xff0c;大多场景对视频水印的要求越来越高&#xff0c;从之前的固定位置静态文字水印、png水…

TIM怎么更新版本 TIM检查更新版本教程

TIM是非常好用的软件&#xff0c;与传统的QQ比起来比较轻便&#xff0c;简洁大方&#xff0c;今天小编教大家怎样TIM检查更新。 TIM检查更新版本教程 首先&#xff0c;打开TIM&#xff0c;如下图所示&#xff0c;TIM是这个图标&#xff0c;如果在metro界面&#xff0c;就是第…

探究C++11智能指针之std::unique_ptr

背景 谈起C&#xff0c;它被公认为最难学的编程语言之一&#xff0c;不仅语法知识点广泛&#xff0c;细节内容之多&#xff0c;学习难度和学习周期也长&#xff0c;导致好多新入行的开发者对C“敬而远之”&#xff0c;甚至“从入门到放弃”。自C11开始&#xff0c;好多C程序员…

C++17新特性之try_emplace与insert_or_assign

由于std::map中&#xff0c;元素的key是唯一的&#xff0c;我们经常遇到这样的场景&#xff0c;向map中插入元素时&#xff0c;先检测map指定的key是否存在&#xff0c;不存在时才做插入操作&#xff0c;如果存在&#xff0c;直接取出来使用&#xff0c;或者key不存在时&#x…

Foxmail邮件字体大小怎么设置 Foxmail字体的设置方法

Foxmail写邮件的时候&#xff0c;想要设置邮件的字体&#xff0c;和字体大小&#xff0c;该怎么设置呢?下面我们就来看看详细的教程。 Foxmail邮件字体大小怎么设置? Foxmail字体的设置方法 1、下载并安装Foxmail邮件客户端。 Foxmail邮件字体大小怎么设置? Foxmail字体的…

C++11/14/17中提供的mutex系列区别

C11/14/17中提供的mutex系列类型如下&#xff1a; 互斥量 C版本 作用 mutex C11 基本的互斥量 timed_mutex C11 timed_mutex带超时功能。在规定的等待时间内&#xff0c;没有获取锁&#xff0c;线程不会一直阻塞&#xff0c;代码会继续执行 recursive_mutex C11 递归…

Unity环境下实现Camera高帧率RTMP推送

Unity下RTMP直播背景方面不再赘述&#xff0c;今天主要讨论的是&#xff0c;Unity环境下&#xff0c;如何实现Camera高帧率RTMP推送&#xff0c;这里提到的高帧率&#xff0c;不再局限于常规环境下的30帧&#xff0c;以VR头显为例&#xff0c;更高的帧率&#xff08;比如50帧&a…

Outlook2010怎么关联邮箱 Outlook邮箱关联的教程

Outlook想要关联自己的邮箱&#xff0c;该怎么关联呢?下面我们就来看看详细的教程。 1、首先我们登录进入我们的Outlook&#xff0c;点击文件-添加账户 Outlook2010怎么关联邮箱? Outlook邮箱关联的教程 2、之后进入我们的添加账户导航&#xff0c;选择第一个电子邮件 Ou…