当前位置: 首页 > news >正文

可变参数模板与包装器

抱歉:铁汁们,最近在做兼职,积累社会经验,多有拖欠,请多多包涵(抱拳)

引子:接上回我们讲了C++11的几种新增,今天就来接着讲C++11中比较有用的二个东西可变参数模板与包装器。

可变参数模板:当我们进行cout来打印时或cin来进行输入时,我们发现我们打印使用任意数量好任意数量类型的东西,你是否会思考为什么呢?其实都是可变参数模板的功劳,那何为可变参数模板呢?

概念:

可变参数模板是C++11引入的一个特性,它允许模板函数或类接受任意数量的模板参数。这种特性极大地增强了模板的灵活性,使得我们可以编写能够接受不确定数量参数的泛型代码。在标准库中,std::coutstd::cin 就是使用了可变参数模板技术的典型例子

可变参数模板的基本语法:

template<typename... Args>
ReturnType functionName(Args&&... args) {
    // 使用args包中的参数
}

这里的 Args... 是一个模板参数包(template parameter pack),而 args... 是一个函数参数包,它们允许函数或类模板接受任意数量的参数。

如何显示参数包里面的参数呢?

一,利用递归

//递归终止函数
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}
// 展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value << " ";ShowList(args...);
}

二,利用逗号表达式

template <class T>
void PrintArg(T t)
{cout << t << " ";
}
//展开函数
template <class ...Args>
void ShowList(Args... args)
{int arr[] = { (PrintArg(args), 0)... };cout << endl;
}

STL容器中的empalce相关接口函数(利用了可变参数模板):

区别:直接构造》》》

但是我们会发现其实差别也不到,as:emplace_back是直接构造了,push_back // 是先构造,再移动构造,其实也还好

实例代码:

#include <vector>
#include <string>
#include <map>int main() {// 使用emplace_back在vector中构造一个字符串std::vector<std::string> strings;strings.emplace_back("Hello, World!");// 使用emplace在map中构造一个键值对std::map<int, std::string> scores;int studentId = 1;scores.emplace(std::piecewise_construct,std::forward_as_tuple(studentId),std::forward_as_tuple("A"));return 0;
}

可变参数的引用:

一,实现print()任意打印!(其实也可以用输出流来打印自定义类型数据)

#include <iostream>// 可变参数模板函数,用于打印任意数量和类型的参数
template<typename... Args>
void print(Args... args) {((std::cout << args << ", "), ...); // 使用C++17的折叠表达式std::cout << "\n"; // 换行
}int main() {print(1, "Hello", 3.14, 'a'); // 打印整数、字符串、浮点数和字符
}

二,你可以使用可变参数模板来实现递归模板函数,例如计算参数包中所有整数的和:

template<typename T>
T sum(T value) {return value;
}template<typename T, typename... Args>
T sum(T first, Args... rest) {return first + sum(rest...);
}int main() {auto total = sum(1, 2, 3, 4, 5); // 计算1+2+3+4+5std::cout << "Total: " << total << std::endl; // 输出15
}

包装器

在C++中,"包装器"可能指的是多种不同的概念,但通常它指的是一种设计模式或技术,用于提供一个接口或包装,以改变或增强现有对象或类型的功能。在C++11中,包装器可能与智能指针、lambda表达式或函数包装有关

function

在C++中,function 是标准库中的一个模板类,位于 <functional> 头文件中。std::function 是一个通用的多态函数包装器,它可以存储、调用和复制任何可调用对象,例如普通函数、Lambda表达式、函数对象以及成员函数指针。

std::function 的主要用途是提供一个可调用的接口,该接口可以与任何类型的可调用实体一起工作,而不需要关心其具体的类型。这使得 std::function 成为实现回调机制、事件处理等模式的理想选择。

注意点:

1,function使用为<返回类型(引用类型,引用类型)>

2,function来包装普通成员函数时要用&,返回要传this*所以我们参数要加一个类*来进行通过

测试代码as:

double e(const int&a,const int&b)
{return (a + b) / 2;
}class b
{
public:double e(const int& a, const int& b){return (a + b) / 3;}
};int main()
{auto vt3 = bind(e, 100, placeholders::_1);cout << vt3(2) << endl;function<double(int, int)> vt = &e;cout << vt(3,3) << endl;function<double(b, int, int)> vt1 = &b::e;function<double(b*, int, int)> vt2 = &b::e;cout << vt1(b(), 3, 3) << endl;b h;cout << vt2(&h, 3, 3) << endl;function<double(int)> vt4 = bind(&b::e, b(),placeholders::_1,100);cout << vt4(2) << endl;return 0;	
}

bind:

std::bind 是 C++ 标准库中的一个函数模板,位于 <functional> 头文件中。它用于创建一个新的可调用对象(通常是一个函数对象),这个新对象将一个或多个参数绑定到一个可调用实体(如函数、Lambda 表达式、成员函数等)的参数上。std::bind 返回一个 std::function 对象,它可以在之后被调用。

底层:

注意点:

1,使用时,可以用来绑定调用顺序,或者进行绑定参数

2,调用bind的一般形式:auto newCallable = bind(callable,arg_list); 其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的 callable的参数。当我们调用newCallable时,newCallable会调用callable,并传给它arg_list中 的参数。 arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是“占位符”,表示 newCallable的参数,它们占据了传递给newCallable的参数的“位置”。数值n表示生成的可调用对 象中参数的位置:_1为newCallable的第一个参数,_2为第二个参数,以此类推

测试代码:

double e(const int&a,const int&b)
{return (a + b) / 2;
}class b
{
public:double e(const int& a, const int& b){return (a + b) / 3;}
};int main()
{auto vt3 = bind(e, 100, placeholders::_1);cout << vt3(2) << endl;function<double(int, int)> vt = &e;cout << vt(3,3) << endl;function<double(b, int, int)> vt1 = &b::e;function<double(b*, int, int)> vt2 = &b::e;cout << vt1(b(), 3, 3) << endl;b h;cout << vt2(&h, 3, 3) << endl;function<double(int)> vt4 = bind(&b::e, b(),placeholders::_1,100);cout << vt4(2) << endl;return 0;	
}

智能指针包装器:


C++11引入了新的智能指针类型,如std::unique_ptr、std::shared_ptr和std::weak_ptr,它们可以被视为原始指针的包装器,提供了自动内存管理。

有趣的连接:(可拿来做题)

感谢大家支持,下次要讲什么?我先来个图,大家猜猜(偷笑)

相关文章:

可变参数模板与包装器

抱歉&#xff1a;铁汁们&#xff0c;最近在做兼职&#xff0c;积累社会经验&#xff0c;多有拖欠&#xff0c;请多多包涵&#xff08;抱拳&#xff09; 引子&#xff1a;接上回我们讲了C11的几种新增&#xff0c;今天就来接着讲C11中比较有用的二个东西可变参数模板与包装器。…...

工业控制常用“对象“数据类型汇总(数据结构篇)

合理巧妙的数据结构会大大简化项目的编程工作量,所以任何项目前期第一步应该是设计巧妙的数据结构、封装对象属性。这样会使我们的编程快捷和高效。这篇博客作为数据类型汇总,会不间断更新。 1、普通电机轴对象 2、普通电机轴对象(详细结构变量) TYPE "udtMotorAxis&q…...

优雅处理枚举前端丢失大Long精度问题

1. 枚举-json处理&#xff08;前端 <> 后端 <> 数据库&#xff09; 前端传递 枚举code 后端响应 枚举code 表里存储 枚举code 内存处理 枚举对象 Getter AllArgsConstructor JsonFormat(shape JsonFormat.Shape.OBJECT) public enum SexEnum {MALE(0, "男&…...

【c/c++】 学习ector 容器笔记

c/c 学习ector 容器笔记 int 型的 vector 容器应该使用什么类型的索引&#xff1f; 对于 int 型的 vector 容器&#xff0c;应该使用 size_t 类型的索引。size_t 是一个无符号整数类型&#xff0c;它在标准库中广泛用于表示大小和索引。它足够大&#xff0c;可以表示任何标准…...

DN专业3D图形制作软件win/mac软件安装下载(附下载链接)

目录 一、软件概述 1.1 Adobe DN简介 1.2 Windows/Mac系统要求 Windows系统&#xff1a; Mac系统&#xff1a; 二、安装步骤 2.1 下载与解压 2.2 安装程序 2.3 启动软件 三、使用教程 3.1 界面介绍 3.2 创建和编辑3D内容 3.3 合成与渲染 四、高级技巧与注意事项 …...

VSCode搭建Hzero(SpringCloud架构)后端开发调试环境

正常情况下我们使用IDEA开发Hzero&#xff0c;但是有的公司是不允许破解或者使用IDEA的&#xff0c;此时可以使用eclipse来替代也是可以的&#xff0c;最近尝试使用VSCode来开发调试发现了一些问题其中最大的问题是Vscdoe在绝大多数情况下是不能直接运行Hzero&#xff0c;使用插…...

【C++】OJ习题(初阶)

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、字符串&#x1f4a5;1.1 字符串相加&#x1f4a5;1.2 验证回文字符串&#x1f4a5;1.3 反转…...

6.4K+ Star!一个强大的本地知识库问答系统,支持多格式文件和跨语言检索,为企业提供高效、安全的数据洞察……

https://github.com/netease-youdao/QAnything 【阅读原文】跳转Github项目 转自AIGC创想者 项目简介 QAnything 是一个基于本地知识库的问答系统&#xff0c;它能够理解和回答基于任何类型文件的问题。 QAnything支持的文件格式非常广泛&#xff0c;包括PDF、Word、PPT、XL…...

mvn编译的时候出现Perhaps you are running on a JRE rather than a JDK 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 mvn编译的时候出现如下问题: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile) on project yudao...

React原理之Fiber详解

前置文章&#xff1a; React原理之 React 整体架构解读React原理之整体渲染流程 -----读懂这一篇需要对 React 整体架构和渲染流程有大致的概念 &#x1f60a;----- 在React原理之 React 整体架构解读中&#xff0c;简单介绍了 Fiber 架构&#xff0c;也了解了 Fiber 节点的…...

远离“优越感”陷阱,拥抱美好人生

在人生的漫长旅程中,我们不断地与他人相遇、相知、相交,在各种关系中寻找温暖、支持与成长。然而,并非所有的关系都如我们所愿,有些关系甚至可能成为我们前进道路上的阻碍。正如我们所知,唯利是图者不可交,但有一种关系比索要金钱更值得警惕,那就是找你索取满足感的关系…...

Redis的线程模型

Redis作为一种基于内存的高性能键值对数据库&#xff0c;其线程模型和IO模型是实现高性能的关键因素。以下将详细探讨Redis的线程与IO模型&#xff0c;内容不少于2000字。 一、Redis的线程模型 Redis的线程模型是理解其高性能的重要基础。在Redis的发展过程中&#xff0c;其线…...

ubuntu24.04安装nginx1.24

ubuntu安装nginx 更新包索引 sudo apt update安装nginx sudo apt install nginx确认安装成功并检查Nginx版本 nginx -v启动Nginx服务 sudo systemctl start nginx设置Nginx开机自启 sudo systemctl enable nginx在浏览器中访问 http://<your_server_IP> 来确认Nginx…...

一款好看的WordPress REST API 主题

介绍&#xff1a; 主题特色&#xff1a; 使用Nuxtjs WordPress Rest Api 实现前后端分离&#xff0c;可完成多端部署&#xff1b; 主题支持自动切换黑夜模式。 使用说明&#xff1a; service 目录为wordpress主题文件&#xff0c;需要拷贝到wordpress主题目录下&#xff0…...

《5G 与区块链融合:智能城市服务质量的飞跃》

在科技飞速发展的时代&#xff0c;5G 技术的普及正以前所未有的速度改变着我们的生活&#xff0c;而区块链技术的兴起也为各领域带来了创新的解决方案。当这两种前沿技术相互结合&#xff0c;将为智能城市的发展注入强大动力&#xff0c;显著提升服务质量&#xff0c;开创更加便…...

前后端分离开发:用 Apifox 高效管理 API

目录 1.前后台分离开发介绍 2.API 2.1 APIfox介绍 2.2 接口文档管理 1.前后台分离开发介绍 前端开发有2种方式&#xff1a;「前后台混合开发」和「前后台分离开发」。 前后台混合开发&#xff0c;顾名思义就是前台后台代码混在一起开发&#xff0c;如下图所示&#xff1a…...

Go Channel 详解

概述 在 Go 语言中&#xff0c;channel 是一种用于在 goroutine 之间传递数据的机制。它提供了同步和通信的能力&#xff0c;使得并发编程变得更加简单和安全。Channel 在 Go 语言中的设计是类型安全的&#xff0c;并且支持发送和接收两种操作。 基本概念 创建通道 创建一个…...

使用FModel提取游戏资产

使用FModel提取游戏模型 前言FModel简介FModel安装FModel使用初次使用资产预览资产导出 附录dumperDumper-7生成usmap文件向游戏中注入dll 前言 这篇文章仅记录我作为初学者使用FModel工具提取某款游戏模型的过程。 FModel简介 FModel是一个开源软件&#xff0c;可以用于查看…...

Qt C++ 屏幕录制 保存mp4

在麒麟系统&#xff08;基于 Linux&#xff09;上优化 Qt C 的屏幕录制&#xff0c;主要针对捕获效率和编码速度。可以参考以下优化策略&#xff1a; 1. 使用更高效的屏幕捕获 API 麒麟系统作为 Linux 系统的一种&#xff0c;可以考虑直接使用 X11、Wayland、或 DRM/KMS API …...

Adobe After Effects的插件--------CC Cylinder

CC Cylinder是柱体插件。它是AE内置的3D插件。 使用条件 该插件的作用是将2D图层转换为3D的柱体。所以使用该插件时要确保源图层为2D的。 我们以一张图片素材为例: 给图片图层添加CC Cylinder效果控件,然后新建一个摄像机(利用摄像机旋转、平移、推拉工具,方便在各个角度…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...