C++类重载函数的function和bind使用
在没有C++11的std::function和std::bind之前,我们使用函数指针的方式是五花八门,结构很繁琐难懂。C++11中提供了std::function和std::bind统一了可调用对象的各种操作。
1.std::function简介
std::function首先是可调用对象,本质上生成了一个类(仿函数)
简单的使用如下代码
#include <unordered_map>
#include <iostream>
#include <functional>
using namespace std;
int func(int a)
{
cout << a << __FUNCTION__ << endl;
return a;
}
int main()
{
using NewType = function<int(int)>; // function本质上生成了一个类(仿函数)
NewType f1 = func;
f1();
return ;
}
2.std::function与std::bind联合使用绑定类成员函数
可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。
std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。std::bind主要有以下两个作用:
将可调用对象和其参数绑定成一个防函数;
只绑定部分参数,减少可调用对象传入的参数。
一个简单的例子:
#include <unordered_map>
#include <iostream>
#include <functional>
using namespace std;
class A
{
public:
int funcA(int a)
{
cout << "111 " << a << endl;
return ;
}
}; int main()
{
A a;
using NewType = function<int(int)>; // function本质上生成了一个类(仿函数)
NewType f1 = bind(&A::funcA, &a, std::placeholders::_1);
f1();
return ;
}
3.std::function与std::bind联合使用绑定类成员重载函数
绑定类成员重载函数的难点在于如何区分函数绑定的是哪一个成员函数。这时需要在函数指针前指定其类型。下面是一个简单的例子:
#include <unordered_map>
#include <iostream>
#include <functional>
using namespace std;
class A
{
public:
int funcA(int a)
{
cout << "111 " << a << endl;
return ;
}
int funcA(int a, int b)
{
cout << "222 " << a << endl;
return a + b;
}
}; int main()
{
unordered_map<int, void *> funcMap;//尝试将其转载入map中
A g;
using NewType1 = function<int(int, int)>;
using NewType2 = function<int(int)>;
NewType1* type1 = new NewType1; // function本质上生成了一个类(仿函数)
NewType2* type2 = new NewType2;
//获取重载函数指针
*type1 = std::bind((int(A::*)(int, int)) & A::funcA, &g, std::placeholders::_1, std::placeholders::_2);
*type2 = std::bind((int(A::*)(int)) & A::funcA, &g, std::placeholders::_1);
//
funcMap[] = type1; //
funcMap[] = type2; // // 使用
void* s1 = funcMap[];
void* s2 = funcMap[];
NewType1* f1 = (NewType1*)(s1);
NewType2* f2 = (NewType2*)(s2);
(*f1)(,);
(*f2)();
return ;
}
最近在工作中,遇到了需要编写大量重复代码的工作,于是尝试将这些重载函数放入映射中,只需要添加注册函数,最终可以统一使用映射表调用所需要的函数,function与bind方法给了我帮助,我也将代码分享给大家。
C++类重载函数的function和bind使用的更多相关文章
- JavaScript 函数绑定 Function.prototype.bind
ECMAScript Edition5 IE9+支持原生,作用为将一个对象的方法绑定到另一个对象上执行. Function.prototype.bind = Function.prototype.bi ...
- C++11的闭包(lambda、function、bind)
c++11开始支持闭包,闭包:与函数A调用函数B相比较,闭包中函数A调用函数B,可以不通过函数A给函数B传递函数参数,而使函数B可以访问函数A的上下文环境才可见(函数A可直接访问到)的变量:比如: 函 ...
- C++ 类的成员函数指针 ( function/bind )
这个概念主要用在C++中去实现"委托"的特性. 但现在C++11 中有了 更好用的function/bind 功能.但对于类的成员函数指针的概念我们还是应该掌握的. 类函数指针 就 ...
- boost::function 通过boost::bind调用类成员函数
1. 首先引用boost::function和boost::bind的头文件和库: #include "boost/bind.hpp" #include "boost/f ...
- 利用C++11的function和bind简化类创建线程
问题引出 当在类中需要创建线程时,总是因为线程函数需要定义成静态成员函数,但是又需要访问非静态数据成员这种需求,来做若干重复性的繁琐工作.比如我以前就经常定义一个静态成员函数,然后定一个结构体,结构体 ...
- C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化
模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...
- C++ Templates (1.5 重载函数模板 Overloading Function Templates)
返回完整目录 目录 1.5 重载函数模板 Overloading Function Templates 1.5 重载函数模板 Overloading Function Templates 和普通函数一 ...
- 重载运算符:类成员函数or友元函数
类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...
- C++类成员函数的重载、覆盖和隐藏区别?
C++类成员函数的重载.覆盖和隐藏区别? a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无.b.覆盖是指派生类函数覆 ...
随机推荐
- SpringCloud系列之API网关(Gateway)服务Zuul
1.什么是API网关 API网关是所有请求的入口,承载了所有的流量,API Gateway是一个门户一样,也可以说是进入系统的唯一节点.这跟面向对象设计模式中的Facet模式很像.API Gatewa ...
- Zookeeper学习(二)
一.Znode节点属性 dataVersion 数据版本, 每次当 Znode 中的数据发生变化的时候, dataVersion都会自增一下cversion 节点版本, 每次当 Znode 的节点发生 ...
- 使用pytorchviz进行模型可视化出现 'NoneType' object has no attribute 'grad_fn'
问题 最近学习pytorch, 原来用kreas重现的模型改为用pytorch实现训练,因为这样给模型的操作更加细致, 对模型的掌控更好. 当我写好一个模型 出现了这个问题 使用pytorchviz进 ...
- 同事不太懂负载均衡,我直接把阿里架构师的这份Nginx笔记甩给他
Nginx功能强大,架构复杂,学习.维护和开发的门槛较高. 本份笔记深入最新的Nginx源码,详细剖析了模块体系.动态插件.功能框架.进程模型.事件驱动.线程池.TCP/UDP/HTTP 处理等Ngi ...
- python基本数据类型(三)
字典{} 冒号前面是key(键)冒号后面是values(值) 键:值 ==键值对 1.索引 s={ 'name':'lifei', 'age':'', 'sex':'man' } print(s[' ...
- C++动态规划
数塔: #include <iostream> using namespace std; int a[1000][1000]; int main(){ int n; cin>> ...
- Linux基础 Day1
Linux-Day1 1.用户登录 root用户 是一个特殊的管理账号,也可以称为超级管理员 root用户对系统有完全控制的权限 对系统的损害会无限大 在工作中,如果没有特殊的必要,尽量不要使用roo ...
- SparkStreaming支持的业务场景
目前而言SparkStreaming 主要支持以下三种业务场景: ➢ 无状态操作:只关注当前的DStream中的实时数据.例如:只对当前DStream中的数据做正确性校验.(下一条与上一条数据无关) ...
- Devops与敏捷二者能否结合?
当前软件行业的趋势倾向于使应用程序开发和部署成为业务运营的重要组成部分.这些公司开始专注于实现像DevOps解决方案这样的方法,这有助于缩短产品开发时间.使用DevOps进行开发减少了交付软件所需的阶 ...
- Jmeter系列(56)- 详解 Weighted Switch Controller 权重控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 它能分配其子项目(Child ...