c++| c++11左右值引用,完美转发,可变参数模板,functional包装器,bind函数

news2025/1/22 12:11:37

c++| c++11的新特性

  • 左,右值引用
    • 什么是左值,右值
    • 左值引用和右值引用
    • 右值引用解决什么问题呢?
    • 移动构造
    • 万能引用
      • 形式
    • 完美转发
      • 格式
  • lambada表达式
    • 格式
  • 可变参数模板
    • 可变参数模板实现打印不同类型
    • emplace_push
    • 以list的emplace_back的实现举例
    • 包装器
    • bind 函数

左,右值引用

什么是左值,右值

左右值的语法上的区别就是能不能取地址。
int a = 10; a 可以取地址 是左值, 但是 10不能取地址 是右值。
常见的右值还有匿名对象,表达式返回值,字面常量(就是直接写出来的值比说刚刚的10)等。

左值引用和右值引用

左值引用 T &val , 右值应用 T&& val
一般的左值引用,只能引用只能引用左值,右值引用只能引用右值。
但是const & 可以引用右值

右值引用解决什么问题呢?

  1. 对于一个函数返回值不能用引用且拷贝开销很大的情况。比如to_string 的返回值 就是string 不能是 &string 因为 它的生命周期只在函数内部。str 出了to_string 就销毁了。

在这里插入图片描述

my::string s1 = my::to_string(123);
// 会经历 str 的构造,拷贝构造临时对象(深拷贝),赋值构造(深拷贝) s1 开销就很大

所以我们用移动构造优化它

移动构造

就是 参数是右值引用的构造。

string(string&& s)
	:_str(nullptr)
{
	cout << "string(string&& s) -- 移动构造" << endl;
	swap(s);
}

// 移动赋值
string& operator=(string&& s)
{
	cout << "string(string&& s) -- 移动赋值" << endl;
	swap(s);

	return *this;
}

在这里插入图片描述
大大节省了深拷贝的成本。
2.匿名对象直接当作函数的参数

string s1 = "hh";
vector<string> v;
v.push_back(s1);

//
v.push_back("hh");

上面的写法先构造s1,然后s1再拷贝构造给v中的data。
下面的写法是构造匿名对象,然后匿名对象直接移动构造给data,就不走深拷贝了。

值得注意的是右值引用本身的属性是左值的因为这样才能修改。左值有常属性。

万能引用

形式

template class<T &&>
void func(T && val)
{
	....	
}

与右值引用的区别就是上面带了个模板,我们传右值他就识别成右值,传左值它识别成左值

完美转发

格式

template class<T &&>
void func(T && val) //万能引用
{
	do_something(forword<T>(val)); // 完美转发
}

完美转发常常和完美应用一起使用的,主要是防止右值引用的属性是左值,传给下一层被认为是左值了,从而走不到移动构造,移动拷贝等。

lambada表达式

lambada表达式本质编译器帮我们生产了一个仿函数。

格式

[]()-> return {} // -> 和return 可省 但是这[] 捕获列表不能省 
//比如
[](int x, int y ) -> return (x+y;);

[=] 传值的方式捕获同一作用域的所有变量
[&]传引用的方式捕获同一作用域的所有变量
还可以混用比如[&,a,b]。 除了a,b 以外按转值捕获,其他按引用捕获。

可变参数模板

template class<...Args>
void func(Args ...args)
{

}

可变参数模板实现打印不同类型

// 编译时确定类型,所以要_cpp_print() 递归到最后,参数为空。
void _cpp_print() 
{

}
template<class T,class ... Args>
void _cpp_print(T & val, Args ...args)
{
	cout << val << " ";
	_cpp_print(args...);
}

template <class ...Args >
void cpp_print(Args... args)
{
	_cpp_print(args...);
}

在这里插入图片描述

template <class T>
int printArg(T &t)
{
	cout << t << " ";
	return 0;
}

template <class ...Args>
void cpp_print(Args...args)
{
	int arr[] = { printArg(args)... };
}

在这里插入图片描述

emplace_push

在这里插入图片描述
emplace_back 用的就是可变参数模板,在参数大于1的情况下,emplace_back 的效率比push_bakc更高。因为push_back 对于左值中间会走构造然后拷贝构造,对于右值会走构造,然后移动构造。
但是emplace_back 是直接传递的参数包,最后底层直接构造。

以list的emplace_back的实现举例

在这里插入图片描述

包装器

function包装器
可以用来接受可调用对象,比如函数指针,仿函数,lambda表达式等。
为什么需要包装器呢?
1)统一接口,提供了一个统一的接口来处理不同类型和形式的可调用对象。这意味着你可以将不同类型的可调用对象作为参数传递给函数,或者将它们存储在一个容器中,而无需关心它们具体的类型。

int f(int a, int b) 
{
	return a + b;
}
class Func
{
public:
	int operator() (int a, int b) 
	{
		return a + b;
	}
};
class Puls 
{
public:
	static int puls(int a, int b) 
	{
		return a + b;
	}
	int puls_(int a, int b) 
	{
		return a + b;
	}
};
int main() 
{
	function<int(int, int)> func1 = f;
	function<int(int, int)> func2 = Func();
	function<int (int, int)> func3 = [](int a, int b) {return a + b; };
	return 0;
}

特别的如果是成员函数

class Puls 
{
public:
	static int puls(int a, int b) 
	{
		return a + b;
	}
	int puls_(int a, int b) 
	{
		return a + b;
	}
};
int main() 
{
	function<int(int, int)> func4 = &Puls::puls; // 对于static 成员函数 可以不用& 但建议都加上&
	function<int(Puls*,int, int)> func5 = &Puls::puls_;
	function<int(Puls,int, int)> func5 = &Puls::puls_; // 特别的下面这种写法也可以,也更推荐这种写法
	func5(Puls(),2,5); 
	return 0;	
}

bind 函数

可以改变参数的顺序和个数

	using  func_t = function<int(int, int)>;


	func_t sub1 = bind(sub,placeholders::_2,placeholders::_1);
	function<int(int)> sub2= bind(sub, 5, placeholders::_1);
	cout << sub2(10) << endl;;

bind函数常常用于类成员函数固定this指针,比如

class Puls 
{
public:
	
	int puls_(int a, int b) 
	{
		return a + b;
	}
};


int main() 
{
	function<int( int, int)> func7 = bind(&Puls::puls_,Puls(), placeholders::_1, placeholders::_2); // 指针可以 对象也可以
	cout<<func7(2,8);

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

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

相关文章

新160个crackme - 020-cosh.3

运行分析 老规矩&#xff0c;需要破解Name和Serial PE分析 c程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida查找关键字符串 分析关键函数&#xff0c;得出以下结论&#xff1a;Name、Serial每一位进行亦或计算&#xff0c;若计算结果相等则弹窗成功 算法分析…

吴恩达机器学习作业-ex7(主成分分析)

data1 导入库&#xff0c;读取数据&#xff0c;并进行可视化数据 import numpy as np import scipy.io as sio import matplotlib.pyplot as plt#读取数据 path "./ex7data1.mat" data sio.loadmat(path) # print(data.keys()) X data.get("X") # pri…

Python数据分析案例58——热门游戏数据分析及其可视化

案例背景 有哪个男生不喜欢玩游戏呢&#xff1f;就算上了班儿也要研究一下游戏以及热门的游戏。正好这里有个热门的游戏数据集&#xff0c;全球热门游戏数据集来做一下一些可视化的分析。 数据介绍 该文件包含一个数据集&#xff0c;详细说明了多个平台上的各种流行游戏。每个…

【Golang 面试 - 进阶题】每日 3 题(十五)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

Cesium 高德地图暗黑化

Cesium 高德地图暗黑化 高德电子地图实现暗黑效果 // 设置图层滤镜new ImageryLayerFilter({viewer: viewer,imageryLayer: imageryLayer,});

YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构和使用方式)

YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构) 本文介绍论文原理介绍网络代码多种yaml设置网络测试及实验结果<!-- 这里放入论文图片 --> &emsp;;本文介绍 本文给大家带来的改进机制是结合MobileNetV4骨干网络,其中来自2024.5月发布的MobileNetV4…

Pageadmin 漏洞教程

上传文件解压拿webshell 用哥斯拉&#xff0c;生成一个asp木马 这个就是我们生成的asp木马 不能直接上传 压缩为zip文件 上传 上传以后我们点击解压 就成功了 然后我们去访问 然后用哥斯拉访问 然后再点击添加 这样就成功了 成功进入

VSCode在windows系统下的配置简单版

参考链接 从零开始的vscode安装及环境配置教程(C/C)(Windows系统)_vscode搭建编译器环境-CSDN博客 vscode生成tasks.json、launch.json、c_cpp_properties.json文件_vscode生成launch.json-CSDN博客 自动生成配置文件简单方便&#xff01;&#xff01;&#xff01; 运行c代…

点击clean失败的操作Error running ‘demo4 [clean]‘ No valid Maven installation found.

错误情况&#xff1a; 解决方法&#xff1a; 重新调整自己的maven&#xff1a; 点击settings&#xff0c;搜索maven&#xff0c;点击进入&#xff1a; 选择自己的真实路径&#xff1a; 效果: 可以发现&#xff0c;运行clean成功&#xff01;

Useless Fan

灵感来源于老外的一个作品&#xff0c;但是只有风扇功能&#xff0c;除了袖珍感觉没啥用。 在淘宝上十几块买了一堆原件&#xff0c;于是手痒&#xff0c;自己手搓了一个&#xff0c;设计了个简单的3D打印外壳。 包括3大功能&#xff1a;风扇&#xff0c;充电宝&#xff08;2…

Spring MVC 快速入门指南及实战演示

1、SpringMVC简介 1.1 背景 Servlet属于web层开发技术&#xff0c;技术特点&#xff1a; 1. 每个请求都需要创建一个Servlet进行处理 2. 创建Servlet存在重复操作 3. 代码灵活性低&#xff0c;开发效率低 是否有技术方案可以解决以上问题&#xff1f; 1.2 SpringMVC概述 Sp…

C#加班统计次数

C#加班统计次数 运行环境&#xff1a;vs2022 .net 8.0 社区版 1、用C#语言&#xff1b;2、有界面上传Excel文件; 3、对Excel列&#xff08;部门、人员姓名、人员编号、考勤时间 &#xff09;处理&#xff1a;&#xff08;1&#xff09;按人员编号、考勤日期分组且保留原来字段&…

矩阵快速幂优化dp

之前一直想找一个矩阵快速幂的专题&#xff0c;但是都没有题目来总结&#xff0c;今天就来水一下 这个题目的转移方程我们可以很快想出来&#xff0c;但是我们如何作为我们矩阵快速幂的敲门砖呢&#xff1f; 有一个问题要注意的是我们由于这题不是取模的&#xff0c;可能会溢出…

网络安全-渗透测试工具及插件介绍和使用方法

1、Burp Suite Burp Suite 是用于攻击web 应用程序的集成平台。 是一款广泛使用的网络安全工具套件&#xff0c;主要用于测试Web应用程序的安全性。它可以帮助安全研究人员、渗透测试人员和开发人员发现和利用Web应用程序中的安全漏洞。 &#xff08;1&#xff09;下载和安装&a…

QuanTide-weekly第1期

本周Po文 这周我们共发表5篇文章。《基于 XGBoost 的组合策略…》等两篇详细讲解了机器学习构建组合策略的框架和常见问题。 文章要点与结论&#xff1a; 通过两阶段式方案实现多因子、多资产的组合策略构建。第一阶段基于XGBoost构建多个多因子单标的模型&#xff0c;第二阶…

安卓基本布局(下)

TableLayout 常用属性描述collapseColumns设置需要被隐藏的列的列号。shrinkColumns设置允许被伸缩的列的列号。stretchColumns设置允许被拉伸的列的列号。 <TableLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/TableL…

yolov3 neck部分搭建,以及完整的网络搭建代码,可直接运行

目录 1. 用来实现共同的一些操作 common_module.py 2.1 使用到的通道配置 net_config.py 2.2 主干网络 darknet53.py 3. predict部分 neck.py 4. 拼凑成完整的yolov3网络 Yolov3.py 5. 网络结构如下 上次提到了搭建了主干网络&#xff0c;这个加上neck就可以构建…

内网穿透--meterpreter端口转发实验

实验背景 通过公司带有防火墙功能的路由器接入互联网&#xff0c;然后由于私网IP的缘故&#xff0c;公网无法直接访问内部主机&#xff0c;则需要通过已连接会话&#xff0c;代理穿透访问内网主机服务。 实验设备 1.路由器一台 2.内网 Win 7一台 3.公网 Kali 一台 4.网络 …

LeetCode面试150——238除自身以外数组的乘积

题目难度&#xff1a;中等 默认优化目标&#xff1a;最小化平均时间复杂度。 Python默认为Python3。 目录 1 题目描述 2 题目解析 3 算法原理及代码实现 3.1 左右乘积列表 参考文献 1 题目描述 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 an…

第十二节、人物下蹲

一、SuB-State Machine(子状态机) 1、创建一个子状态 2、可以选择退出的动画 二、人物下蹲 1、人物动画下蹲 2、人物碰撞体下蹲