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

C++11第四弹:包装器

在这里插入图片描述

🌈个人主页: 南桥几晴秋
🌈C++专栏: 南桥谈C++
🌈C语言专栏: C语言学习系列
🌈Linux学习专栏: 南桥谈Linux
🌈数据结构学习专栏: 数据结构杂谈
🌈数据库学习专栏: 南桥谈MySQL
🌈Qt学习专栏: 南桥谈Qt
🌈菜鸡代码练习: 练习随想记录
🌈git学习: 南桥谈Git

🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈
本科在读菜鸡一枚,指出问题及时改正

文章目录

  • 包装器
    • function包装器
      • 应用场景
      • 包装成员函数指针
    • bind
      • 调整参数顺序
      • 调整参数个数

包装器

包装器是一个类模板

C++中的可调用对象:函数指针(类型定义很复杂)、仿函数对象(定义一个类的时候,用的时候有些麻烦,其次不适合统一类型)、lambda(没有类型概念)、包装器

function包装器

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

std::function在头文件<functional>
类模板原型:

template <class T> function; // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;

模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参
在这里插入图片描述

他不是用来定义可调用对象,是用来包装可调用对象:
在这里插入图片描述

#include<functional>int f(int a, int b)
{return a + b;
}struct Functor
{
public:int operator() (int a, int b){return a + b;}
};int main()
{function<int(int, int)> fc1;//包装函数指针function<int(int, int)> fc2 = f;cout << fc2(1, 2) << endl;//包装仿函数function<int(int, int)> fc3 = Functor();cout << fc3(2, 3) << endl;//包装lambda表达式function<int(int, int)> fc4 = [](int x, int y) {return x + y; };cout << fc4(3, 4) << endl;return 0;
}

在这里插入图片描述

应用场景

力扣:150.逆波兰表达式求值

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;//命令和对应的函数动作结合map<string,function<int(int,int)>> opfuncMap={{"+",[](int a,int b){return a+b;}},{"-",[](int a,int b){return a-b;}},{"*",[](int a,int b){return a*b;}},{"/",[](int a,int b){return a/b;}}};for(auto& str:tokens){if(opfuncMap.count(str)) // 是操作符{function<int(int,int)> func=opfuncMap[str];int right=st.top();st.pop();int left=st.top();st.pop();st.push(func(left,right));}else //是操作数 {st.push(stoi(str));}}return st.top();}
};

在这里插入图片描述

包装成员函数指针

在包装静态成员指针函数时,当我们需要用到某个函数时,需要在前面指定类域。但如果不是静态时,不仅需要添加类域,还需要添加一个&

class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};int main()
{function<int(int, int)> fc1 = Plus::plusi;cout << fc1(1, 2) << endl;function<double(Plus*, double, double)> fc2 = &Plus::plusd;Plus plus;cout << fc2(&plus, 1.1, 2.2) << endl;function<double(Plus, double, double)> fc3 = &Plus::plusd;//Plus plus;cout << fc3(Plus(), 1.1, 2.2) << endl;return 0;
}

fc1 是一个 std::function<int(int, int)> 对象,绑定到静态成员函数 Plus::plusi。调用 fc1(1, 2) 输出 3

fc2 是一个 std::function<double(Plus*, double, double)> 对象,绑定到非静态成员函数 Plus::plusd。它接受一个 Plus* 指针和两个 double 类型的参数。调用 fc2(&plus, 1.1, 2.2) 计算 1.1 + 2.2 并输出 3.3

bind

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

原型:

template <class Fn, class... Args>
bind (Fn&& fn, Args&&... args);
with return type (2)	
template <class Ret, class Fn, class... Args>
bind (Fn&& fn, Args&&... args);

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

调用bind的一般形式:auto newCallable = bind(callable,arg_list);

调整参数顺序

int Sub(int a, int b)
{return a - b;
}int main()
{auto f1 = Sub;cout << f1(10, 5) << endl;auto f2 = bind(Sub, placeholders::_2, placeholders::_1);cout << f2(10, 5) << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述

调整参数个数

class Sub
{
public:int sub(int a, int b){return a - b;}
};int main()
{Sub sub;auto f3 = bind(&Sub::sub, Sub(), placeholders::_2, placeholders::_1);cout << f3(10, 5) << endl;return 0;
}

参数顺序:bind(&Sub::sub, &s, _2, _1) 绑定了成员函数 sub s 对象,并指定 _2_1 的位置。调用 f3(10, 5) 会将 5 映射到 _210 映射到 _1,因此 f3(10, 5) 实际上会调用 s.sub(5, 10),结果是 5 - 10,即 -5

在这里插入图片描述


http://www.mrgr.cn/news/26073.html

相关文章:

  • 干货分享,大厂内部压测方案设计
  • 详说 类和对象
  • 深入探索系统架构设计
  • 队列的实现(C语言)
  • 供应RM500UCNAB-D10-SNADA模块
  • Anaconda安装
  • 软件测试的类型
  • 图像分类架构
  • 外贸网站建设该怎么做
  • 数字化转型背景下低代码开发模式变革的研究
  • 【6大设计原则】解锁代码的灵活性:深入解析开闭原则的代码实例与应用
  • Android主副屏显示-Android13
  • mysql把某一个字段的值中的aa,替换成bb
  • 乐鑫云平台 ESP RainMaker® 携手亚马逊云科技登陆国内市场
  • 欧洲麻花钻市场主要企业市场占有率及排名
  • [论文笔记] CSFCN
  • pytorch入门(1)——pytorch加载数据初认识
  • 高并发内存池项目(5)——实现PageCache
  • IDEA 怎么编辑文件模板
  • 使用 PyTorch 从头开始​​构建您自己的 Llama 3 架构