C++11--包装器与可变参数摸板

2023-11-07

可变参数模板

C++11的新特性可变参数模板能够让我们创建可以接受可变参数的函数模板和类模板

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args... args,这个擦拭农户包中可以包含0到任意个模板参数
template<class ...Args>
void show(Args... args){}

上面的参数args前面有省略号,所以它就是一个可变模板参数,我们把带省略号的参数称为“参数包”,它里面包含了0到N个模板参数。我们无法直接获取参数包args中的每个参数,只能通过展开参数包的方式来获取参数包中的每个参数。

递归函数方式展开参数包
#include <iostream>
using namespace std;
// 递归终止函数
template<class T>
void showlist(T t)
{
	cout << t << endl; // 当参数包只剩下最后一个参数时,会适配这个函数
}

// 递归函数
template <class T, class ...Args>
void showlist(T val, Args... args)
{
	cout << val << endl;
	showlist(args...); // 通过递归调用,函数会自动适配参数个数,此处的三个...不能省略
}

int main()
{
	showlist(1);
	showlist(1, "fff");
	showlist(3, 1.1, string("hello"));
	return 0;
}

在这里插入图片描述

函数包装器

function包装器也叫做适配器,C++中的function本质是一个类模板,也是一个包装器

我们都知道一个函数func有可能是一个函数,有可能是一个函数指针,有可能是一个仿函数,也有可能是一个lambda表达式。这些都是可调用的类型,如此丰富的类型,可能会导致模板的效率低下。q

举个例子
#include <iostream>
using namespace std;
template <class T, class F>
void func(T t, F f)
{
	static int a = 0; // 如果模板只实例化一次,每个a的地址是一样的
	cout << &a << endl;
}

int main()
{
	func(1, 1);
	func(1, 1.1);
	func('1', 2);
	return 0;
}

在这里插入图片描述

可以发现通过函数模板去实例化的函数是三分不同的函数。

// 通过函数包装器使用函数
#include <functional>
#include <iostream>
#include <functional>

template <class T, class F>
void fun(T t, F f)
{
	static T x;
	x = t;
	std::cout << typeid(t).name() << std::endl;
}

class functest
{
public:
	int add(int x, int y)
	{
		return x + y;
	}

	static int mul(int x, int y)
	{
		return x * y;
	}
};

int main()
{
	functest ft;
	// 使用包装器,包装成员函数,需要加上类类型
	std::function<int(functest,int, int)> f1 = &functest::add;
	std::cout << f1(functest(),1, 2) << std::endl;
	// 使用包装器,包装静态成员函数,不需要加上类类型
	std::function<int(int, int)> f2 = &functest::mul;
	std::cout << f2(2, 3) << std::endl;
	// 使用包装器包装lambda表达式
	double x = 1.2;
	std::function<double(double)> f3 = [&](double y)->double { return x *= y; };
	std::cout << f3(4) << std::endl;
	return 0;
}

bind函数

std::bind函数定义在头文件中,是一个函数模板,他像一个函数包装器(适配器),接受一个可调用对象,生成一个新的可调用对象来“适应”对象的参数列表。一般而言,我们用它可以把一个原本接收N个参数的函数,通过绑定一些参数,返回一个接收M个(M可以大于N)参数的新函数。同时,使用std::bind函数还可以实现参数顺序调整等操作。

// bind函数的原型
template <class Fn, class ...Args>
bind(Fn&&, Args&& ...args);

可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表,使用方法如下:

auto newCallable = bind(callable, arg_list);
举个例子
// bind函数使用举例
#include<iostream>
#include<functional>

class functest
{
public:
	int add(int x, int y)
	{
		return x + y;
	}

	
};

double mutl(double x, double y)
{
	return x * y;
}

int main()
{
	// 将mutl函数的第一个参数固定为1,后面在调用函数的时候只需要传一个参数
	std::function<double(double)> fun1 = std::bind(mutl, 1 , placeholders::_1);
	std::cout << fun1(2.1) << std::endl;
	// 使用bind函数绑定成员变量
	std::function<int(int, int)> fun2 = std::bind(&functest::add, functest(), placeholders::_1, placeholders::_2);
	std::cout << fun2(1, 2) << std::endl;
	return 0;
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11--包装器与可变参数摸板 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 如何从 .resx 文件条目获取注释

    资源文件中的字符串有名称 值和注释 The ResXResourceReader类让我可以访问名称和值 有办法看评论吗 你应该能够得到Comment via ResXDataNode class http msdn microsoft co
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • c++设计模式

    C 是一种面向对象的编程语言 支持许多设计模式 以下是几种常见的设计模式 1 单例模式 Singleton Pattern 确保一个类只有一个实例 并提供一个全局访问点 来访问该实例 2 工厂模式 Factory Pattern 定义一个接
  • kafka笔记3--快速部署KRaft版本的kafka3.1.1

    kafka笔记3 快速部署KRaft版本的kafka3 1 1 1 介绍 2 部署测试 2 1 部署 2 2 测试 3 注意事项 4 说明 1 介绍 Apache Kafka Raft 是一种共识协议 它的引入是为了消除 Kafka 对 Z
  • 【Java愚公】gitlab设置中文

    gitlab设置中文 设置步骤 设置完成后效果图 设置步骤 gitlab版本自带了中文语言包 可以通过上述方式直接切换 设置流程说明如下 访问gitlab服务 在用户偏好设置中设置用户语言类别 如下图所示 设置完成后效果图
  • 【STM32】电子时钟(1)

    一直想系统的学习STM32 但是公司的项目主要是电机算法 每天看到头都快炸了 打算仿照手机上的时钟应用写一个电子时钟 因为这个任务的定位是 好吧 就没有定位 主要是边玩边学 也不设时间期限和具体的功能指标 有空了就搞搞 想到了什么就加上去
  • 成功解决Myeclipse2017破解时遇到的crack.bat文件闪退问题

    解决问题 解决Myeclipse2017破解时遇到的crack bat文件闪退问题 解决方法 是环境变量设置有错 1 新建系统环境变量 JAVA HOME D Program Files MyEclipse2017CI7 binary co
  • Linux 音视频开发杂记之一-环境配置使用vscode

    开发环境 开发环境选择window10 Visual Studio Code ubuntu20 64 虚拟机 一Windows 安装 1 安装git for windows 安装过程直接下一步 主要原因是windows OpenSSH在vs
  • Flutter - Route传参

    Navigator 组件支持通过使用通用标识符从应用程序的任何地方导航到特定路由 在某些情况下 你可能还希望能够传递参数给特定路由 例如 你希望导航到 user 路由并携带上用户信息 在 Flutter 中 你能通过提供额外的 argume
  • 博客使用方法

    这里写自定义目录标题 凯哥英语视频 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左
  • 数据模型所描述的内容包括三个部分:数据结构、数据操作、数据约束。

    http www cnblogs com joechinochl articles 5252518 html 数据模型所描述的内容包括三个部分 数据结构 数据操作 数据约束 1 数据结构 数据模型中的数据结构主要描述数据的类型 内容 性质以
  • 大数据毕业设计题目选题推荐

    文章目录 0 前言 1 如何选题 1 1 选题技巧 如何避坑 重中之重 1 2 为什么这么说呢 1 3 难度把控 1 4 题目名称 1 5 最后 2 大数据 选题推荐 2 1 大数据挖掘类 2 2 大数据处理 云计算 区块链 毕设选题 2
  • if语句c语言编程题,c语言if语句的练习题答案

    1 编写程序输入a和b 求a和b的余数和商 includevoid main int a b scanf printf 商为 d 余数为 d 2 输入一个整型数据 分别求出各位数字 如 469 则个位数是9 十位数是6 百位数 是4 inc
  • 某型雷达的报文收发实录

    某型雷达的报文收发实录 前言 工作中需要与某型激光雷达进行通讯 读写报文解析出相应的角度 位置 在目前的工作中 切实遇到的问题是报文的收发 这里记录之 以下内容尚未进过实践检验2020 6 20 激光雷达的报文的接收 使用的API为wins
  • matlab怎么搭建神经网络,matlab实现神经网络算法

    怎样用matlab建立bp神经网络 net train net p t 把这句改成net train net p t 试试 matlab应该默认使用列向量 或者直接使用matlab提供的图形界面取训练 在命令行输入nnstart 谷歌人工智
  • 递归求解迷宫问题

    package com yg recursion author GeQiLin date 2020 2 24 16 01 public class MiGong private static int col 7 private static
  • Codeforces Round 881 (Div. 3) 题解

    目录 A Sasha and Array Coloring 题意 思路 代码 B Long Long 题意 思路 代码 C Sum in Binary Tree 题意 思路 代码 D Apple Tree 树形dp 题意 思路 代码 E T
  • 2022年C语言程序设计题库习集带答案(史上最全版)

    C语言程序设计 试题一 一 填空题 1 C语言中基本的数据类型有 2 C语言中普通整型变量的类型说明符为 在内存中占 字节 有符号普通整型的数据范围是 3 整数 35在机内的补码表示为 4 执行下列语句int a 8 a a a a 后 a
  • springboot集成微信app支付

    一 准备工作 以下信息需要自行开通和申请 public static final String APP ID app的id 需要app应用 public static final String KEY api密钥 商户账户信息里面去获取 p
  • 一个mysql语句报错引发的故事

    昨天在自己的本上装了mysql 打算练习sql语句 在创建表的时候报了错 Invalid default value for sex 就是说我sql语句中有个性别的默认值设置是无效的 性别用的是enum数据类型 出错原因是因为数据库的编码不
  • 【Python字典】

    字典类型的基本概念 通过任意键信息查找一组数据中值信息的过程叫映射 Python语言中通过字典实现映射 Python语言中的字典可 以通过大括号 建立 建立模式如下 lt 键1 gt lt 值1 gt lt 键2 gt lt 值2 gt l
  • C++11--包装器与可变参数摸板

    文章目录 可变参数模板 递归函数方式展开参数包 函数包装器 举个例子 bind函数 举个例子 可变参数模板 C 11的新特性可变参数模板能够让我们创建可以接受可变参数的函数模板和类模板 Args是一个模板参数包 args是一个函数形参参数包