C++11(中)

新增默认成员函数

C++11之前,默认成员函数有六个,构造函数,析构函数,拷贝构造,拷贝赋值重载,取地址重载,const 取地址重载。

C++11增加了 移动构造 和 移动赋值重载

如果类没有实现移动构造,且没有实现析构,拷贝,拷贝赋值重载中的任意一个,才会生成默认的移动构造。

默认的移动构造对内置类型进行按字节拷贝,自定义类型调用它的移动构造,该自定义类型没有实现移动构造就调用拷贝构造。

默认的移动赋值的生成和调用逻辑也类似。

新增关键字

default : 强制生成默认的成员函数

delete :强制禁用默认的成员函数

可变模板参数

C++11之后,模板可以接受多个参数

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}
//引用接收(万能引用)  
template <class ...Args>
void ShowList(Args&&... args)
{}

实现一个打印函数

//递归的出口
void _my_print() { ;
}
//递归解析参数包 (args...)
template <class T, class... Args> 
void _my_print(T x, Args... args) {  cout << x << endl; _my_print(args...);
}
//打印函数,可以传入不同类型的参数
template <class... Args>
void my_print(Args... args) {_my_print(args...);            
}

调用一下

int main() { my_print(2025,1.1, 'c', string("C++"));   return 0;
}

结果如下

上述代码是在编译时,递归式解析参数包

STL容器的 emplace_back 系列

STL的容器增加了 emplace_back 接口,功能和和 push_back 一样。

以 std::vector 为例,看一下接口

template< class... Args >
void emplace_back( Args&&... args );

emplace_back 支持了模板的可变参数,假如我用插入一个 pair<string, int> 类型的数据,emplace_back 只需传入 string 和 int 类型的参数即可,无需构造临时的 pair<string, int> 对象。

我们分析如下代码,来理解一下

	vector<pair<string, int>> v; v.push_back({ "西瓜", 2 });           v.emplace_back("西瓜", 2);

首先,{ “西瓜”, 2 } 是列表初始化,相当于隐式类型转换,会调用pair的构造函数来构造出pair<string, int>类型的临时对象,该临时对象属于右值,会调用vector的移动构造转移资源,所以

v.push_back({ “西瓜”, 2 }) 插入是pair的构造 + vector的移动构造

而 emplace_back 相当于传参给vector的构造,vector直接构造pair<string, int>类型对象并插入容器中。

v.emplace_back(“西瓜”, 2) 的插入只调用了vector的构造

所以从效率上说:对于浅拷贝的类或内置类型,emplace_back 效率更高。对于深拷贝的类,效率相差不大。

lambda表达式

lambda 表达式是一个匿名函数对象,语法如下

[捕捉列表](参数)mutable -> 返回值类型 {函数体};

lambda 表达式中很多内容可以省略

如下代码

auto func = []() {};
func();

写一个add函数,如下代码

//也可以不带返回值类型 [](int a, int b) { return a + b; };
auto add = [](int a, int b)->int { return a + b;};
cout << add(3, 4) << endl;

捕捉列表可以捕捉当前作用域的变量,加 & 符号表示传引用捕捉,不加表示传值捕捉(lambda表达式会拷贝一份新的副本)

如下代码,传值捕捉,新的副本具有 const属性

int main() { int a = 3, b = 4;//lambda表达式中的 a b 是 mian 函数a b 的一份拷贝auto add = [a, b]() { return a + b; };cout << add() << endl;

取消传值捕捉的 const 属性需要加 mutable 关键字

    auto add = [a, b]() mutable { return a + b; } ;

传引用捕捉如下代码

    int a = 3, b = 4;auto add = [&a, &b]() mutable { a++; b++; };add();cout << a << b << endl;

其他的一些捕捉凡是如下,可以和上述的捕捉方式混合使用。

[=]:表示值传递方式捕获所有父作用域(包含lambda函数的语句块)中的变量(包括this)

[&]:表示引用传递捕捉所有父作用域中的变量(包括this)

[this]:表示值传递方式捕捉当前的this指针

function 包装器

function 的本质是类模板,用来包装一切可调用对象。

可调用对象包括:函数指针,仿函数,函数名,lambda表达式。

// 类模板原型如下
template <class T> function;     // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;
//Ret: 被调用函数的返回类型
//Args…:被调用函数的形参

std::function 的实例化需要指定返回值类型,和参数类型

function<返回值类型(参数类型...)> 对象名 = 可调用对象;

如下示例

int f(int a, int b)
{return a + b;
}
std::function<int(int, int)> func1 = f;
//调用func1
func1(1, 2);

function 类模板重载了 () ,调用该对象可以和仿函数一样。

对于非静态成员函数,可调用对象需要 & 符号,静态成员函数不需要

class op {  
public:static int sub(int a, int b) {return a - b;}int sum(int a, int b) {return a + b;       }
};function<int(op*, int, int)> f1 = &op::sum; 
function<int(int, int)> f2 = op::sub;

std::bind

bind 是一个函数模板,接受一个可调用对象,生成一个新的可调用对象。bind 用来调整参数的顺序和个数。

// 原型如下:
template <class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
// with return type (2) 
template <class Ret, class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);

以上述的 op 类举例,绑定成员函数

op p;
function<int(int, int)> f3 = bind(&op::sum, &p, placeholders::_1, placeholders::_2);        
function<int(int, int)> f4 = bind(&op::sum, p, placeholders::_1, placeholders::_2);

placeholders::_n ,是占位符,不需要绑定的参数用 placeholders::_n 表示。

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

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

相关文章

强化学习笔记——4策略迭代、值迭代、TD算法

基于策略迭代的贝尔曼方程和基于值迭代的贝尔曼方程&#xff0c;关系还是不太理解 首先梳理一下&#xff1a; 通过贝尔曼方程将强化学习转化为值迭代和策略迭代两种问题 求解上述两种贝尔曼方程有三种方法&#xff1a;DP&#xff08;有模型&#xff09;&#xff0c;MC&#xff…

计算机网络 笔记 网络层 3

IPv6 IPv6 是互联网协议第 6 版&#xff08;Internet Protocol Version 6&#xff09;的缩写&#xff0c;它是下一代互联网协议&#xff0c;旨在解决 IPv4 面临的一些问题&#xff0c;以下是关于 IPv6 的详细介绍&#xff1a; 产生背景&#xff1a; 随着互联网的迅速发展&…

【搜索回溯算法篇】:拓宽算法视野--BFS如何解决拓扑排序问题

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索&#xff08;BFS&#xff09;解决拓扑排…

23.Word:小王-制作公司战略规划文档❗【5】

目录 NO1.2.3.4 NO5.6​ NO7.8.9​ NO10.11​ NO12​ NO13.14 NO1.2.3.4 布局→页面设置对话框→纸张&#xff1a;纸张大小&#xff1a;宽度/高度→页边距&#xff1a;上下左右→版式&#xff1a;页眉页脚→文档网格&#xff1a;勾选只指定行网格✔→ 每页&#xff1a;…

视频脚本生成器(基于openai API和streamlit)

utils.py&#xff1a; # 所有和ai交互的代码放进utils.py里&#xff08;utils 通常是 “utilities” 的缩写&#xff0c;意为 “实用工具” 或 “实用函数”&#xff09;from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from lan…

Android --- CameraX讲解

预备知识 surface surfaceView SurfaceHolder surface 是什么&#xff1f; 一句话来说&#xff1a; surface是一块用于填充图像数据的内存。 surfaceView 是什么&#xff1f; 它是一个显示surface 的View。 在app中仍在 ViewHierachy 中&#xff0c;但在wms 中可以理解为…

Longformer:处理长文档的Transformer模型

Longformer&#xff1a;处理长文档的Transformer模型 摘要 基于Transformer的模型由于自注意力操作的二次复杂度&#xff0c;无法处理长序列。为了解决这一限制&#xff0c;我们引入了Longformer&#xff0c;其注意力机制与序列长度呈线性关系&#xff0c;使其能够轻松处理数…

python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像匹配

【1】引言 前序学习了图像的常规读取和基本按位操作技巧&#xff0c;相关文章包括且不限于&#xff1a; python学opencv|读取图像-CSDN博客 python学opencv|读取图像&#xff08;四十九&#xff09;原理探究&#xff1a;使用cv2.bitwise()系列函数实现图像按位运算-CSDN博客…

MySQL为什么默认引擎是InnoDB ?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL为什么默认引擎是InnoDB &#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL为什么默认引擎是InnoDB &#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 默认引擎是 InnoDB&#xff0c;主要…

蓝桥杯真题k倍区间

题目如下 代码解析&#xff1a; 成功AC

python项目之requirements.txt文件

Python项目中可以包含一个 requirements.txt 文件&#xff0c;用于记录所有依赖包及其精确的版本号用以新环境部署。 当我们开发新项目的时候&#xff0c;会用virtualenv创建很多python独立环境&#xff0c;这时候就会出现在不同环境下安装相同的模块的情况&#xff0c;这时候…

算法题(53):对称二叉树

审题&#xff1a; 需要我们判断二叉树是否满足对称结构&#xff0c;并返回判断结果 思路&#xff1a; 方法一&#xff1a;递归 其实是否对称分成两部分判断 第一部分&#xff1a;根节点是否相等 第二部分&#xff1a;根节点一的左子树和根节点二的右子树是否相等&#xff0c;根…

使用 cmake

使用前注意 : CMake是一种跨平台的构建系统&#xff0c;它用于管理软件构建过程&#xff0c;尤其适合多语言、多配置的项目。CMake不直接构建软件&#xff0c;而是生成特定构建工具&#xff08;如Makefile或Visual Studio项目&#xff09;所需的配置文件。 如果仅仅使用 qt 编…

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先&#xff0c;要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理&#xff0c;还是其他功能&#xff1f;明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时&#xff0c;你需要选择适合的编程语言、…

学习数据结构(5)单向链表的实现

&#xff08;1&#xff09;头部插入 &#xff08;2&#xff09;尾部删除 &#xff08;3&#xff09;头部删除 &#xff08;4&#xff09;查找 &#xff08;5&#xff09;在指定位置之前插入节点 &#xff08;6&#xff09;在指定位置之后插入节点 &#xff08;7&#xff09;删除…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构&#xff0c;通过 Key 可以快速查找到对应的 Value。B 树索引由根页面&#xff08;Root&am…

Vue-cli 脚手架搭建

安装node.js 官网下载node.js安装包&#xff0c;地址&#xff1a;Node.js — Download Node.js 先在node.js即将要安装的路径下创建两个文件夹&#xff1a;node_cache&#xff08;缓存&#xff09;、node_global&#xff08;全局&#xff09; 点击安装包&#xf…

深度解析 DeepSeek R1:强化学习与知识蒸馏的协同力量

DeepSeek-R1 的问世&#xff0c;无疑在 AI 领域激起了千层浪。自发布仅一周&#xff0c;它便凭借卓越的性能和创新的技术&#xff0c;成为 AI 社区热议的焦点&#xff0c;代表着人工智能在推理和理解能力上的重大飞跃。今天我们一起深度解析一下DeepSeek-R1 一、强大基石&…

openssl 生成证书 windows导入证书

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

笔记本搭配显示器

笔记本&#xff1a;2022款拯救者Y9000P&#xff0c;显卡RTX3060&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz&#xff0c;无DP1.4口 显示器&#xff1a;2024款R27Q&#xff0c;27存&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz &…