C++进阶:C++11相关
◆博主名称少司府欢迎来到少司府的博客☆*: .. o(≧▽≦)o ..:*☆⭐数据结构系列个人专栏初阶数据结构_少司府的博客-CSDN博客⭐C基础个人专栏C初阶_少司府的博客-CSDN博客⭐琢玉成器终有时笔底生花夺锦归目录1. 列表初始化1.1 C98中的{}1.2 C11中的{}1.3 C11中的initializer_list2.右值引用和移动语义2.1 右值和左值2.1.1 左值2.1.2 右值2.2 左值引用和右值引用2.3 延长生命周期2.4 左值和右值的参数匹配2.5 右值引用和移动语义的使用场景2.5.1 左值引用使用场景2.5.2 右值引用和移动语义使用场景3. 类型分类4. 引用折叠和完美转发4.1 引用折叠4.2 完美转发1. 列表初始化1.1 C98中的{}在C98中利用{}初始化的情况有两种结构体的初始化和数组的初始化。struct Point { int _x; int _y; }; int main() { int arr[]{1,2,3,4,5}; Point p{1,2}; return 0; }1.2 C11中的{}1、C11以后试图实现一切对象皆可用{}初始化{}初始化也叫做列表初始化。2、内置类型和自定义类型都可以列表初始化自定义类型列表初始化本质就是类型转换。// C11⽀持的 // 内置类型⽀持 int x1 { 2 }; // ⾃定义类型⽀持 // 这⾥本质是⽤{ 2025, 1, 1}构造⼀个Date临时对象 // 临时对象再去拷⻉构造d1编译器优化后合⼆为⼀变成{ 2025, 1, 1}直接构造初始化d1 Date d1 { 2025, 1, 1 };3、列表初始化const引用的临时对象。// 这⾥d2引⽤的是{ 2024, 7, 25 }构造的临时对象 ,临时对象具有常性 const Date d2 { 2024, 7, 25 };4、需要注意的是C98⽀持单参数类型转换时也可以不⽤{}Date d3 { 2025 }; // C11 Date d4 2025; // C985、在列表初始化的时候可以省略// 可以省略掉 Point p1{ 1, 2 }; int x2{ 2 }; Date d6{ 2024, 7, 25 }; const Date d7{ 2024, 7, 25 }; // 不⽀持只有{}初始化才能省略 // Date d8 2025;6、在多参数类型构造对象的时候列表初始化会方便很多。vectorDate v; v.push_back(d1); v.push_back(Date(2025, 1, 1)); // ⽐起有名对象和匿名对象传参这⾥{}更有性价⽐ v.push_back({ 2025, 1, 1 });1.3 C11中的initializer_listC11提供一个类模板initializer_list这是它的文档initializer_list - C Reference有了initializer_list我们可以实现n个值去初始化构造一个容器对象// 构造拷贝构造优化 vectorint v1 { 1,2,3,4 }; vectorint v2{ 1,2,3,4 }; // 构造两者的构造都是隐式类型转换为initializer_listint类型 vectorint v3({ 1,2,3,4,5 });initializer_list特点{ }内括起来的数据类型是一样的。2.右值引用和移动语义C11之前学习的都是左值引用C11之后增加了右值引用的概念两者本质都是给对象取别名。2.1 右值和左值2.1.1 左值左值是一个表示数据的表达式一般具有持久状态可以取地址可以出现在赋值符号的左右两边const修饰的左值不能更改它的数据但是可以取地址。// 左值可以取地址 // 以下的p、b、c、*p、s、s[0]就是常⻅的左值 int* p new int(0); int b 1; const int c b; *p 10; string s(111111); s[0] x; double x 1.1, y 2.2;如图常见的左值一般包括变量名、计算表达式*p、p等、函数调用表达式s[ 0 ]返回类型是引用Ref可以修改。2.1.2 右值右值也是一个表示数据的表达式一般不具有持久状态不能取地址只能出现在赋值符号的右边。// 以下⼏个10、x y、fmin(x, y)、string(11111)都是常⻅的右值 10; x y; fmin(x, y); string(11111);如图常见的右值包括字面量常量、表达式返回的临时对象、匿名对象、函数的非引用返回等。2.2 左值引用和右值引用1、左值引用来引用左值右值引用来引用右值// 左值引⽤给左值取别名 int r1 b; int* r2 p; int r3 *p; string r4 s; char r5 s[0]; // 右值引⽤给右值取别名 int rr1 10; double rr2 x y; double rr3 fmin(x, y); string rr4 string(11111);2、左值引用不能直接引用左值但是const左值引用可以引用右值const int rx1 10;3、右值引用不能直接引用左值但是右值引用可以引用move(左值)move的本质就是类型转换左值表达式变成将亡值。move(b); // 不改变b本身的状态 int rrx1 move(b); // move是一个函数模板4、注意变量表达式本身是左值的属性也就是说一个右值引用的变量名本身是左值属性的// 这⾥要注意的是rr1的属性是左值所以不能再被右值引⽤绑定除⾮move⼀下 int r6 rr1; // 普通左值引用 int 只允许绑定左值;rr1 是具名变量表达式rr1属于左值匹配绑定规则编译通过。 // int rrx6 rr1; int rrx6 move(rr1);5、语法上左值引用和右值引用都是取别名不开空间汇编上两者都是指针实现的指令都是一样的。2.3 延长生命周期右值引用和const左值引用都可以延长临时对象的生命周期但是const引用的对象不能被修改。std::string s1 Test; // std::string r1 s1; // 错误不能绑定到左值 const std::string r2 s1 s1; // OK到 const 的左值引⽤延⻓⽣存期 // r2 Test; // 错误不能通过到 const 的引⽤修改 std::string r3 s1 s1; // OK右值引⽤延⻓⽣存期 r3 Test; // OK能通过到⾮ const 的引⽤修改 std::cout r3 \n;2.4 左值和右值的参数匹配1、C98中我们实现一个const左值引用作为参数的函数那么左值右值都可以匹配2、C11之后我们要重载实现对应匹配的函数void f(int x) { std::cout 左值引⽤重载 f( x )\n; } void f(const int x) { std::cout const 的左值引⽤重载 f( x )\n; } void f(int x) { std::cout 右值引⽤重载 f( x )\n; }2.5 右值引用和移动语义的使用场景先给出以下代码class Solution { public: // 传值返回需要拷⻉ string addStrings(string num1, string num2) { string str; int end1 num1.size() - 1, end2 num2.size() - 1; // 进位 int next 0; while (end1 0 || end2 0) { int val1 end1 0 ? num1[end1--] - 0 : 0; int val2 end2 0 ? num2[end2--] - 0 : 0; int ret val1 val2 next; next ret / 10; ret ret % 10; str (0 ret); } if (next 1) str 1; reverse(str.begin(), str.end()); return str; } // 这⾥的传值返回拷⻉代价就太⼤了 vectorvectorint generate(int numRows) { vectorvectorint vv(numRows); for (int i 0; i numRows; i) { vv[i].resize(i 1, 1); } for (int i 2; i numRows; i) { for (int j 1; j i; j) { vv[i][j] vv[i - 1][j] vv[i - 1][j - 1]; } } return vv; } };当前两个函数是实现字符串相加和杨辉三角的逻辑。2.5.1 左值引用使用场景回顾一下左值引用主要使⽤场景是——在函数中左值引⽤传参和左值引⽤传返回值时减少拷⻉同时还可以修改实参和修改返回对象的价值。但是如果遇到这个情况——要返回的对象的作用域只在当前函数栈帧出了作用域就销毁了就不能直接返回左值引用。如上述两个函数。这里就需要用到右值引用来解决这个问题。在C11之前该问题可以靠输出型参数解决void addStrings(const string num1, const string num2, string res) { res.clear(); // 清空原有内容复用内存 int i num1.size() - 1; int j num2.size() - 1; int carry 0; while (i 0 || j 0) { int v1 i 0 ? num1[i--] - 0 : 0; int v2 j 0 ? num2[j--] - 0 : 0; int sum v1 v2 carry; carry sum / 10; res.push_back(sum % 10 0); } if (carry ! 0) { res.push_back(1); } reverse(res.begin(), res.end()); }如图要返回的res需要手动传入。这时候可能有疑惑既然出了当前栈帧就会销毁那可以在堆上开辟空间new一个res吗绝对不可以调用者不知道返回的对象是堆上开辟的没有手动释放的话会引发内存泄漏2.5.2 右值引用和移动语义使用场景右值引用使用场景局部对象出了当前函数就销毁了不能传左值引用只能传右值引用。string s6 Solution().addStrings(11111, 22222); // 右值引用延长临时对象的生命周期,两个参数可以通过移动构造减少拷贝构造带来的消耗 cout s6.c_str() endl;移动构造和移动赋值// 移动构造 string(string s) { cout string(string s) -- 移动构造 endl; swap(s); } // 移动赋值 string operator(string s) { cout string operator(string s) -- 移动赋值 endl; swap(s); return *this; }两者都是通过swap交换将亡值的资源来实现构造大大减少了拷贝带来的消耗。rmove::string s5 move(s1); // 触发移动构造move之后移动构造导致s1的资源被释放 //cout s1.c_str() endl; error3. 类型分类1、C11以后进一步对类型进行了划分右值被分为纯右值(pure value简称prvalue)和将亡值(expiring value简称xvalue)。2、纯右值指的是那些字面量常量或求值结果相当于字面值或是一个不具名的临时对象。例如42、true、nullptr或者类似str.substr(1,2)、str1 str2传值返回函数调用或者整型a、baab等。3、将亡值指的是返回右值引用的函数的调用表达式和转换为右值引用的转换函数的表达式。例如move(x)、static_castX(x)4、泛左值(generalized value简称glvaue)包括将亡值和左值4. 引用折叠和完美转发4.1 引用折叠1、C中不能直接定义引用的引用但可以通过模板或者typedef中的类型操作可以构成引用的引用。int r i; // error,直接报错2、在构成引用的引用的时候C给出了一个引用折叠的规则右值引用的右值引用折叠成右值引用其他都折叠成左值引用。typedef int lref; typedef int rref; lref r1 n; // r1 的类型是 int lref r2 n; // r2 的类型是 int rref r3 n; // r3 的类型是 int rref r4 1; // r4 的类型是 int当然我们也可以通过模板来观察templateclass T void Function(T t) { int a 0; T x a; //x; cout a endl; cout x endl endl; } void test_04() { // 10是右值推导出T为int模板实例化为void Function(int t) Function(10); // 右值 int a; // a是左值推导出T为int引⽤折叠模板实例化为void Function(int t) Function(a); // 左值 // std::move(a)是右值推导出T为int模板实例化为void Function(int t) Function(std::move(a)); // 右值 const int b 8; // a是左值推导出T为const int引⽤折叠模板实例化为void Function(const int t) // 所以Function内部会编译报错x不能 Function(b); // const 左值 // std::move(b)右值推导出T为const int模板实例化为void Function(const int t) // 所以Function内部会编译报错x不能 Function(std::move(b)); // const 右值 }4.2 完美转发templateclass T class list { typedef list_nodeT Node; public: typedef list_iteratorT, T, T* iterator; typedef list_iteratorT, const T, const T* const_iterator; // 万能引用 templateclass X void push_back(X x) { insert(end(), forwardX(x)); } };如图完美转发forward可以保留x原本的类型。即如果没有forward若引用折叠之后X类型是右值引用x是某个右值的引用但是x本身(变量名)是左值直接传仍然为左值forward则可以保留x右值引用的属性。

相关新闻

C++实现WAV音频波形可视化:从文件解析到图形绘制完整指南

C++实现WAV音频波形可视化:从文件解析到图形绘制完整指南

1. 项目概述与核心价值最近在整理一些老旧的音频处理项目时,翻到了一个自己几年前写的C小工具,核心功能就是读取标准的WAV音频文件,然后把里面的声音数据画成波形图。这玩意儿虽然看起来简单,不就是读文件画图嘛,但真正…

2026/10/11 9:14:24 阅读更多 →
Swift 6新特性解析:并发安全与性能优化

Swift 6新特性解析:并发安全与性能优化

1. Swift 6 的版本演进与核心定位Swift 6 并非简单的增量更新,而是 Apple 在语言设计上一次战略性的集中突破。从版本演进路线来看,Swift 5.1 到 5.10 的每个重要里程碑都在为这次大版本更新铺路。2019 年的 Swift 5.1 引入模块稳定性,为 Swi…

2026/10/8 18:38:49 阅读更多 →
Python Pygame回合制卡牌对战游戏开发全流程解析

Python Pygame回合制卡牌对战游戏开发全流程解析

1. 项目概述与核心价值最近在社区里看到不少朋友对用Python做小游戏很感兴趣,尤其是卡牌对战这种既有策略性又有视觉反馈的类型。我自己也一直觉得,Pygame是Python入门游戏开发一个绝佳的跳板,它足够轻量,又能让你接触到游戏开发的…

2026/10/11 21:38:20 阅读更多 →

最新新闻

TreeSet/TreeMap内容被覆盖?根因藏在可变对象和比较器里

TreeSet/TreeMap内容被覆盖?根因藏在可变对象和比较器里

做Java开发这些年,TreeSet和TreeMap我用得不算少。排序去重、排行榜维护、区间查询这些场景,它们都是非常趁手的工具。但我得坦白说,前阵子在一套内部排行榜模块里,我竟然被这两个容器搞得焦头烂额——业务方反馈榜单上的人变少了…

2026/10/12 9:14:51 阅读更多 →
计算机基础真题解析:ACID、BTree、TCP/IP与编程陷阱

计算机基础真题解析:ACID、BTree、TCP/IP与编程陷阱

简介:本资源是专为中国移动校招应聘者打造的2025年在线测评笔试实战题库,聚焦计算机基础核心能力考察,适用于应届生笔试冲刺与技术岗求职备考。题库覆盖编程语言(C/Java/C/Python面向对象特性辨析)、计算机网络&#x…

2026/10/12 9:14:51 阅读更多 →
用Python实现简谱转调:从首调到绝对音高的自动化处理

用Python实现简谱转调:从首调到绝对音高的自动化处理

前阵子一个朋友给我一份简谱,1C,4/4拍,排练时想让主唱试试F调,问我能不能把整张谱子转一下。打印出来看了一眼,虽说只有两页,但真手写转调的话,每个音都要单独换算,碰上高低音点和临…

2026/10/12 9:14:51 阅读更多 →
REA模型入门:资源-事件-代理建模原理与应用

REA模型入门:资源-事件-代理建模原理与应用

我无法基于当前输入生成符合要求的博文。原因如下:项目标题为单个字母组合“rea”,无明确语义指向,不属于任何可识别的技术术语、产品名、领域缩写或常见概念(如REA在不同语境中可能指代“Real Estate Agent”“Resource-Event-Ag…

2026/10/12 9:13:50 阅读更多 →
宝塔面板部署与优化实战:从安装到进阶的完整指南

宝塔面板部署与优化实战:从安装到进阶的完整指南

1. 宝塔面板部署前,先想清楚这三件事宝塔面板这东西,圈子里的人基本都听过。有人把它当救星,有人把它当累赘。我用了差不多六年,从最早的5.x版本一路跟到现在的9.x,中间踩过的坑能写满一个笔记本。如果你正准备给自己的…

2026/10/12 9:13:50 阅读更多 →
Service Mesh流量治理实战:灰度、熔断与限流落地及成本剖析

Service Mesh流量治理实战:灰度、熔断与限流落地及成本剖析

Service Mesh 这个东西,圈子里讨论了好几年,贬褒不一。我自己的感觉是:流量治理这三板斧——灰度、熔断、限流——既有不可替代的价值,也有被严重低估的代价。灰度这个词,做图像处理的人想到的是像素亮度,做…

2026/10/12 9:13:48 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →