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并不持有字符串的内存,所以它的生命周期一定要比源字符串的生命周期长,源字符串被消毁,行为未定义。

C++17新特性之std::string_view相关推荐

  1. C++11/14/17 新特性总结

    C++11/14/17 新特性总结 initializer_list std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -2 ...

  2. C++11 新特性之std::thread

    C++11 新特性之std::thread 原文:https://blog.csdn.net/oyoung_2012/article/details/78958274 从C++11开始,C++标准库已 ...

  3. 2022年最细Java 17新特性,是真的猛,被征服了!

    SpringBoot 正式支持Java 17,Kafka3.0弃用Java8 Spring Boot 2.5.5是Spring Boot 第一个支持Java 17的版本.现在你已经可以从Spring ...

  4. k8s v1.17 新特性预告: 拓扑感知服务路由

    大家好,我是 roc,来自腾讯云容器服务(TKE)团队,今天给大家介绍下我参与开发的一个 k8s v1.17 新特性: 拓扑感知服务路由. 01 名词解释 拓扑域: 表示在集群中的某一类 " ...

  5. Java 17新特性,快到起飞?惊呆了!

    都说Java 8 是YYDS,那你注意到 Java 17 也是长期支持版本吗?目前按计划 JDK 19 将于今年 9 月发布 SpringBoot 正式支持Java 17,Kafka3.0弃用Java ...

  6. C++17新特性总结

    参考链接:C++17 一.语言特性 1.1 折叠表达式 C++17中引入了折叠表达式,主要是方便模板编程,分为左右折叠,下图为其解包形式: template <typename... Args& ...

  7. C++17 新特性介绍

    文章目录 一.C++ 标准发布历史 二.基本语言特性 1. 结构化绑定 结构化绑定的两点优势 一个使用结构化绑定来改进代码的例子 2. 带初始化的`if` 和`switch` 语句 2.1 带初始化的 ...

  8. c++17新特性_每个开发者都应该了解的一些C++特性

    C++ 是一种强大的编程语言,但也因为其复杂性一直让用户望而却步.后来,C++ 决定做出改变,然后发展至今,成了编程社区最受欢迎的语言之一.C++ 有一些新特性非常好用,本文对此进行了介绍,比如 au ...

  9. C++17新特性学习笔记

    c++17最新特性笔记 1.基本语言特性 ​ 这一部分介绍了 C++17中新的核心语言特性,但不包括那些专为泛型编程(即 template)设计的特性. 结构化绑定 结构化绑定允许你用一个对象的元素或 ...

最新文章

  1. 1组合逻辑电路--多路选择器与多路分解器
  2. LeetCode Add and Search Word - Data structure design(字典树)
  3. ARX中的Purge
  4. Android之给控件添加水纹波效果
  5. 前端学习(689):for循环执行相同代码
  6. 冻存样品对单细胞测序影响大吗?
  7. chrome浏览器功能介绍
  8. ctfshow-萌新-web12( 利用命令执行函数获取网站敏感信息)
  9. 图--广度优先遍历/深度优先遍历(c语言实现)
  10. VMware Workstation 12 pro + 激活码+VMware Workstation 10 + 激活码
  11. 如何下载和安装iOS 15公测版【附更新建议】
  12. Linux下常用的串口助手 —— minicom、putty、cutecom
  13. 艾司博讯:拼多多怎么设置团长ID?团长权限?
  14. 【深入理解TcaplusDB技术】详细介绍TDR表
  15. TeamTalk IM_PDUBASE详解
  16. 鸿蒙系统sp3什么意思,XP系统的那个SP3是什么意思?
  17. 淘宝直通车展现位置和人群精准如何运用
  18. 稳压集成块LM78XX LM79XX
  19. 8、ARM嵌入式系统:UART初始化
  20. matlab制作天体运动动画,天体运动 动态演示

热门文章

  1. html 提交后跳转页面,html 提交后跳转页面
  2. php获取蓝凑云文件列表,php调用蓝奏云下载接口
  3. 贪吃蛇程序 php,微信小程序-贪吃蛇教程实例
  4. 字符串查找字符出现次数_查找字符串作为子序列出现的次数
  5. JavaScript | 数组的常用属性和方法
  6. php fpm www.conf,PHP7中php.ini、php-fpm和www.conf 配置
  7. micropython移植教程_【教程】智能编程T-Watch手表初试micropython之电子秤教程
  8. java bitset_Java BitSet length()方法与示例
  9. Python | 查找字符串中每个字符的频率
  10. ## c 连接字符_用于字符比较的C#程序