C++17中std::string_view的使用
为了解决std::string初始化(或拷贝)成本高昂的问题,C++17引入了std::string_view。std::string_view提供对现有字符串(C风格字符串、std::string、或另一个std::string_view)的只读访问,而无需进行拷贝。当想要有效地处理和操作字符串而不修改它们时,通常使用std::string_view。
int test_string_view_copy()
{std::string str1{ "china" };std::string_view strv1{ "beijing" };// str2和str1的数据存放在完全不同的两个位置(副本); strv2和strv1的数据都指向同一个指针地址,没有额外的拷贝(副本)std::string str2{ str1 };std::string_view strv2{ strv1 };std::cout << "str2: " << str2 << ", strv2: " << strv2 << "\n"; // str2: china, strv2: beijingstr1.clear();strv1 = {}; //strv1 = strv1.substr(0, 0); //strv1.remove_prefix(strv1.size()); // 注意它们的区别// clear str1完全不会影响到str2; "clear" strv1也不会影响到strv2,因为strv2指向的指针地址没有变,对strv1 "clear"操作并不会影响到它之前指向的指针地址数据std::cout << "str2: " << str2 << ", strv2: " << strv2 << "\n"; // str2: china, strv2: beijingreturn 0;
}
std::string为模板类std::basic_string<char>,而std::string_view为模板类std::basic_string_view<char>。如下,其中CharT为character type。
template<class CharT,class Traits = std::char_traits<CharT>,class Allocator = std::allocator<CharT> >
class basic_string;template<class CharT,class Traits = std::char_traits<CharT> >
class basic_string_view;using string = basic_string<char>;
using string_view = basic_string_view<char>;
模板类std::basic_string的声明参考: https://en.cppreference.com/w/cpp/header/string
模板类std::basic_string_view的声明参考:https://en.cppreference.com/w/cpp/header/string_view
std::basic_string有析构函数,而std::basic_string_view没有析构函数。
std::string_view优点:
1.轻便:主要用于提供字符串的视图(view),使std::string_view拷贝字符串的过程非常高效,永远不会创建字符串的任何副本,不像std::string会效率低下且导致内存开销。std::string_view不拥有字符串数据,它仅提供对现有字符串的视图或引用(view or reference)。这使得它适合需要访问或处理字符串而无需内存分配或重新分配开销的场景.
2.轻量高效:由于std::string_view不管理内存,因此它具有最小的内存占用。分配或拷贝std::string_view既快速又便宜,因为它只涉及拷贝字符串的引用、长度和起始位置。
3.更好的性能:std::string_view比const std::string&更好,因为它消除了在字符串的最开头有一个std::string对象的约束,因为std::string_view由两个元素组成:第一个是const char*,指向数组的起始位置,第二个是size。
4.std::string_view提供了std::string提供的成员函数的子集,主要集中于只读操作。虽然你可以访问字符并执行搜索,但无法修改std::string_view的内容。这种不变性确保了操作的安全性,并保证所查看的字符串保持不变。
注意:
1.与C字符串和std::string在字符串末尾需要字符串终止符('\0')不同,std::string_view不需要空终止符来标记字符串的结尾。因为它记录了字符串的长度。
2.从概念上讲,std::string_view只是字符串的视图,不能用于实际修改字符串。创建std::string_view无需拷贝数据。
3.std::string_view可以使用许多不同类型的字符串进行初始化:C格式字符串、std::string、或另一个std::string_view。C风格字符串和std::string都会隐式转换为std::string_view。但std::string_view不会隐式转换为std::string:因为std::string会拷贝初始值(这是昂贵的),所以C++不允许将std::string_view隐式转换为std::string。这是为了防止意外地将std::string_view参数传递给std::string参数,以及无意中在可能不需要此类副本的情况下创建昂贵的副本。如果需要,可以有两个选择:
(1).使用std::string_view初始值显式创建std::string;
(2).使用static_cast将现有的std::string_view转换为std::string.
以下为测试代码:注意注释说明
int test_string_view_functions()
{// unlike std::string, std::string_view has full support for constexprconstexpr std::string_view strv{ "china beijing" };// substrauto strv1 = strv.substr(6);std::cout << "strv1: " << strv1 << std::endl; // strv1: beijing//strv1[0] = 'B'; // 无论strv是不是constexpr, strv1都不能作修改char str1[]{ "beijing" };std::string_view strv2{ str1 };std::cout << "strv2: " << strv2 << std::endl; // strv2: beijingstr1[0] = 'B';std::cout << "strv2: " << strv2 << std::endl; // strv2: Beijingstd::cout << "at 2: " << strv2.at(2) << ", back: " << strv2.back() << "\n"; // at 2: i, back: gstrv2.remove_prefix(3);std::cout << "remove_prefix 3: " << strv2 << "\n"; // remove_prefix 3: jingstrv2.remove_suffix(2);std::cout << "remove_suffix 2: " << strv2 << "\n"; // remove_suffix 2: jistd::string str{};strv.copy(str.data(), strv.size()); // 注意str并非完整的std::string对象,str.size()为0std::cout << "str: " << str.data() << "\n"; // str: china beijing note:是str.data()而不能是str// 注意以下两条语句的差异, str.size()为0std::cout << "strv.compare(str.data()): " << strv.compare(str.data()) << "\n"; // strv.compare(str.data()): 0std::cout << "strv.compare(str): " << strv.compare(str) << "\n"; // windows: strv.compare(str): 1 linux: strv.compare(str): 13auto found = strv.find(strv2);std::cout << "found: " << found << "\n"; // found: 9std::cout << "strv rfind: " << strv.rfind("i") << "\n"; // strv rfind: 10std::cout << "strv find_first_of: " << strv.find_first_of("i") << "\n"; // strv find_first_of: 2std::cout << "strv find_last_of: " << strv.find_last_of("i") << "\n"; // strv find_last_of: 10std::cout << "strv find_last_not_of: " << strv.find_last_not_of("in") << "\n"; // strv find_last_not_of: 12std::cout << "strv find_first_not_of: " << strv.find_first_not_of("in", 1) << "\n"; // strv find_first_not_of: 1// std::string_view不需要空终止符来标记字符串的结尾,因为它记录了字符串的长度char name[]{ 'c', 'h', 'i', 'n', 'a' };std::string_view strv3{ name, std::size(name) };std::cout << "strv3: " << strv3 << "\n"; // strv3: chinastd::cout << "name: " << name << "\n"; // windows: name: china烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘐?宋 linux: name: chinaBeijing// std::string_view to std::string: std::string_view不会隐式转换为std::stringstd::string str2{ strv }; // explicit conversionstd::cout << "str2: " << str2 << "\n"; // str2: china beijing// std::string_view to C-style string: std::string_view -> std::string -> C-style stringauto str3{ str2.c_str() };std::cout << "str3 length: " << strlen(str3) << "\n"; // str3 length: 13// std::string_view just only a viewauto addr = [] {std::string str_csdn{ "https://blog.csdn.net/fengbingchun/" };std::string_view strv_csdn{ str_csdn };std::cout << "strv csdn: " << strv_csdn << "\n"; // strv csdn: https://blog.csdn.net/fengbingchun/return strv_csdn;};std::string_view strv4{ addr() };std::cout << "strv4 csdn: " << strv4 << "\n"; // windows: strv4 csdn: 葺葺葺葺葺葺葺葺葺葺葺葺葺葺葺葺葺 linux: strv4 csdn: ▒(a▒▒\▒▒G▒cn.net/fengbingchun/// literals for std::string_view: 可以通过在双引号字符串文字后面使用sv后缀来创建类型为std::string_view的C风格字符串常量using namespace std::string_literals; // access the s suffixusing namespace std::string_view_literals; // access the sv suffixstd::cout << "foo\n"; // no suffix is a C-style string literalstd::cout << "goo\n"s; // s suffix is a std::string literalstd::cout << "moo\n"sv; // sv suffix is a std::string_view literalreturn 0;
}
执行结果如下图所示:

GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:
C++17中std::string_view的使用
为了解决std::string初始化(或拷贝)成本高昂的问题,C17引入了std::string_view。std::string_view提供对现有字符串(C风格字符串、std::string、或另一个std::string_view)的只读访问,而无需进行拷贝。当想要有效地处理和操作字符串而不修改它们时&#…...
C#,数值计算——分类与推理Phylo_nj的计算方法与源程序
1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_nj : Phylagglom { public double[] u; public override void premin(double[,] d, int[] nextp) { i…...
element-ui 图片压缩上传
picture.js export const compressImgNew (file) > {return new Promise(resolve > {const reader new FileReader()const image new Image()image.onload (imageEvent) > {const canvas document.createElement(canvas) // 创建画布const context canvas.getCo…...
【Java 进阶篇】Java XML约束:确保数据一致性和有效性
XML(可扩展标记语言)是一种常用的数据交换格式,用于存储和交换数据。然而,为了确保数据的一致性和有效性,通常需要定义XML约束。XML约束是一种规则集,定义了XML文档的结构、元素、属性和数据类型。本篇博客…...
第一章概述
一、学习目的与要求 本章对软件测试作了概括性的介绍,目的是使学生对软件测试有个初步的认识。通过本章的学习,应使学生掌握软件测试的基本概念,了解软件测试的发展历程和行业现状,掌握软件测试技术的分类,理解软件测试…...
XCode15与iOS17/17.1 真机测试问题处理
XCode15与iOS17/17.1 真机测试问题处理,网上相关博客很多,摘录了如下实践后能起作用的地址如下:Xcode 15 报错处理 - 简书iOS17版本适配-CSDN博客 Xcode15适配-六虎 主要介绍下:Assertion failure in void _UIGraphicsBeginImag…...
使用 Rust 和 cURL 库下载程序
以下是一个使用 Rust 和 cURL 库的下载器程序,用于下载 图像。此程序使用了 https://www.duoip.cn/get_proxy 的代码。 extern crate curl; use std::io::{self, Read}; use std::error::Error; fn main() {let url "https://www.baidu.com";let …...
三维模型表面积计算方法
【版权声明】 本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 更多算法总结请关注我的博客:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。 本文章来自于专栏《Python三维模型处理基础》的系列文…...
unity脚本_力 c#
创建一个脚本 将代码挂载到物体上 取消物体的重力 运行即向z轴运动 加力之后 是否停止是由阻力影响 如果阻力为零 则会一直运动 如果希望就算有阻力也让物体一直动就将加力代码放在Update函数里 using UnityEngine; public class Power : MonoBehaviour{ Rigidbody rigidBo…...
LeetCode 面试题 10.05. 稀疏数组搜索
文章目录 一、题目二、C# 题解 一、题目 稀疏数组搜索。有个排好序的字符串数组,其中散布着一些空字符串,编写一种方法,找出给定字符串的位置。 示例1: 输入: words [“at”, “”, “”, “”, “ball”, “”, “”, “car”, “”, “”…...
分类预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入分类预测
分类预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于BiLSTM-…...
Sobel算子详解及例程
Sobel算子是一种经典的边缘检测算子,被广泛应用于图像处理领域。它基于图像亮度的变化率来检测边缘的位置,主要通过计算图像中像素点的梯度来实现。 Sobel算子分为水平和垂直两个方向的算子,记作Gx和Gy。它们分别对图像进行水平和垂直方向的…...
ScrapeKit 和 Swift 编写程序
以下是一个使用 ScrapeKit 和 Swift 编写的爬虫程序,用于爬取 图片。同时,我们使用了proxy 这段代码来获取代理。 import ScrapeKit class PeopleImageCrawler: NSObject, ScrapeKit.Crawler {let url: URLlet proxyUrl: URL init(url: URL, proxy…...
Java基础面试题知识点总结(上篇)
大家好,我是栗筝i,从 2022 年 10 月份开始,我持续梳理出了全面的 Java 技术栈内容,一方面是对自己学习内容进行整合梳理,另一方面是希望对大家有所帮助,使我们一同进步。得到了很多读者的正面反馈。 而在 2…...
STM32进行LVGL裸机移植
本文的移植参考的是正点原子的课程《手把手教你学LVGL图形界面编程》 基于该课程和《LVGL开发指南_V1.3》“第二章 LVGL 无操作系统移植”,然后结合自身的实际情况进行整理。 先根据自己的习惯,创建基础的单片机工程,然后在APP业务层和DRIVE…...
python解析robot framework的output.xml并生成html
一、用pyh模块解析stat结点数据(output.py) #codingutf-8import xml.dom.minidom import xml.etree.ElementTree#打开xml文档 dom xml.dom.minidom.parse(./ui/output.xml);root2 xml.etree.ElementTree.parse(./ui/output.xml) #得到文档元素对象 ro…...
【RuoYi移动端】uni-app中的单击和双击事件
1、单击事件: click"enterpriseSelect" 2、双击事件: touchend"userinfo"...
使用 conda 在 Ubuntu 16.04 上安装 Python 3.9 的步骤:和 VSCode配置
一、使用conda在 Ubuntu 16.04 上安装 Python 3.9 的步骤: 当然可以,conda 是一个非常强大的包管理器,它可以方便地管理不同版本的 Python 和各种库包。以下是使用 conda 在 Ubuntu 16.04 上安装 Python 3.9 的步骤: 1. 安装 Miniconda Miniconda 是 Anaconda 的轻量级版…...
spring6-国际化:i18n | 数据校验:Validation
文章目录 1、国际化:i18n1.1、i18n概述1.2、Java国际化1.3、Spring6国际化1.3.1、MessageSource接口1.3.2、使用Spring6国际化 2、数据校验:Validation2.1、Spring Validation概述2.2、实验一:通过Validator接口实现2.3、实验二:B…...
【MicroSoft Edge】格式化的显示JSON格式的数据
当我们没有进行任何操作的时候,默认浏览器给我们展示的JSON的数据是这样的: 看着十分不便。 解决方案: 首先点击 MicroSoft Edge 浏览器右上角的三点,如何选择扩展 点击 获取Microsoft Edge 扩展 搜索 JSONView,第一…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
