std::cunction() 简单描述
function是一组函数对象包装类的模板,实现了一个泛型的回调机制。
引入头文件
#include <functional>
using namespace std;
using namespace std::placeholders; //bind的时候会用`
参考:http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html
fuction bind:http://blog.csdn.net/fjb2080/article/details/7527715
我们可以调用的对象有很多,比如普通函数、函数指针、lanmbda表达式、函数对象和类的成员函数等。
不管采用哪种方式,主要调用形式一样(返回值类型、传递给调用的实参类型),我们就可以使用同一种形式来调用。
这个时候就可以用到function模板,它给予我们在调用的方式上更大的弹性。
请看一下三种不同的函数定义:
- int add(int a, int b){
- return a+b;
- }
- auto mod=[](int a, int b){return a%b;};
- struct divide{
- int operator()(int m, int n){
- return m/n;
- }
- };
这三种都可以使用同一种调用形式,int(int, int),调用方式如下:
- function<int(int,int)> func1= add;
- function<int(int,int)> func2= divide();
- function<int(int,int)> func3= mod;
- cout<<func1(5, 6)<<endl;
- cout<<func2(5, 6)<<endl;
- cout<<func3(5, 6)<<endl;
学会了使用function,可以继续如下进行抽象定义,不同类型采用相同的调用方法:
- map<string,function<int(int, int)>> funs =
- {
- {"+", add},
- {"-", std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客
- {"/", divide()},//类成员函数
- {"*", [](int i,int j){return i*j;}},//lambda表达式
- {"%", mod},
- };
- funs["+"](4,6);
以上就是function的简单使用。下面是从另一篇博客转载的,使用function的引用来保存函数对象。考虑下面代码:
- class CAdd
- {
- public:
- CAdd():m_nSum(0){NULL;}
- int operator()(int i)
- {
- m_nSum += i;
- return m_nSum;
- }
- int Sum() const
- {
- return m_nSum;
- }
- private:
- int m_nSum;
- };
- int main(int argc, const char * argv[])
- {
- CAdd cAdd;
- function<int(int)> funcAdd1 = cAdd;
- function<int(int)> funcAdd2 = cAdd;
- cout<<funcAdd1(10)<<endl;
- cout<<funcAdd2(10)<<endl;
- cout<<cAdd.Sum()<<endl;
- return 0;
- }
上面的输出结果是 10 10 0。我们将同一个函数对象赋值给了两个function,然后分别调用这两个function,但函数中的成员变量的值没有保存,问题在哪里?因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1,f2中保存的都是cAdd对象的拷贝。
C++11提供了ref和cref函数来提供对象的引用和常引用的包装。要是function能够正确保存函数对象的状态,可以如下修改代码:
- function<int(int)> funcAdd3 = ref(cAdd);
- function<int(int)> funcAdd4 = ref(cAdd);
- cout<<funcAdd3(10)<<endl;
- cout<<funcAdd4(10)<<endl;
- cout<<cAdd.Sum()<<endl;
另外,两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝。如果源function保存的是对函数对象的引用,则目标function保存的也是函数对象的引用。
//=====================================================================
• cplusplus.com:http://www.cplusplus.com/reference/functional/function/
• cppreference.com:http://en.cppreference.com/w/cpp/utility/functional/function
std::function简介
• 类模板声明
// MS C++ 2013 template<class _Fty> class function; template<class _Fty> class function : public _Get_function_impl<_Fty>::type { ... }// GCC 4.8.2 template<typename _Signature> class function; template<typename _Res, typename... _ArgTypes> class function<_Res(_ArgTypes...)>: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, private _Function_base { ... } // cplusplus.comtemplate <class T> function; // undefined template <class Ret, class... Args> class function<Ret(Args...)>;
• 类模板说明
std::function是一个函数包装器模板,最早来自boost库,对应其boost::function函数包装器。在c++0x11中,将boost::function纳入标准库中。该函数包装器模板能包装任何类型的可调用元素(callable element),例如普通函数和函数对象。包装器对象可以进行拷贝,并且包装器类型仅仅只依赖于其调用特征(call signature),而不依赖于可调用元素自身的类型。
一个std::function类型对象实例可以包装下列这几种可调用元素类型:函数、函数指针、类成员函数指针或任意类型的函数对象(例如定义了operator()操作并拥有函数闭包)。std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。
• 模板参数说明
以cplusplus.com中描述的原型说明:
T : 通用类型,但实际通用类型模板并没有被定义,只有当T的类型为形如Ret(Args...)的函数类型才能工作。
Ret : 调用函数返回值的类型。
Args : 函数参数类型。
std::function详解
• 包装普通函数
#include <iostream> #include <functional> using namespace std;int g_Minus(int i, int j) {return i - j; }int main() {function<int(int, int)> f = g_Minus;cout << f(1, 2) << endl; // -1return 1; }
• 包装模板函数
#include <iostream> #include <functional> using namespace std;template <class T> T g_Minus(T i, T j) {return i - j; }int main() {function<int(int, int)> f = g_Minus<int>;cout << f(1, 2) << endl; // -1return 1; }
• 包装lambda表达式
#include <iostream> #include <functional> using namespace std;auto g_Minus = [](int i, int j){ return i - j; };int main() {function<int(int, int)> f = g_Minus;cout << f(1, 2) << endl; // -1return 1; }
• 包装函数对象
非模板类型:
#include <iostream> #include <functional> using namespace std;struct Minus {int operator() (int i, int j){return i - j;} };int main() {function<int(int, int)> f = Minus();cout << f(1, 2) << endl; // -1return 1; }
模板类型:
#include <iostream> #include <functional> using namespace std;template <class T> struct Minus { T operator() (T i, T j){return i - j;} };int main() {function<int(int, int)> f = Minus<int>();cout << f(1, 2) << endl; // -1return 1; }
• 包装类静态成员函数
非模板类型:
#include <iostream> #include <functional> using namespace std;class Math { public:static int Minus(int i, int j){return i - j;} };int main() {function<int(int, int)> f = &Math::Minus;cout << f(1, 2) << endl; // -1return 1; }
模板类型:
#include <iostream> #include <functional> using namespace std;class Math { public:template <class T>static T Minus(T i, T j){return i - j;} };int main() {function<int(int, int)> f = &Math::Minus<int>;cout << f(1, 2) << endl; // -1return 1; }
• 包装类对象成员函数
非模板类型:
#include <iostream> #include <functional> using namespace std;class Math { public:int Minus(int i, int j){return i - j;} };int main() {Math m;function<int(int, int)> f = bind(&Math::Minus, &m, placeholders::_1, placeholders::_2);cout << f(1, 2) << endl; // -1return 1; }
模板类型:
#include <iostream> #include <functional> using namespace std;class Math { public:template <class T>T Minus(T i, T j){return i - j;} };int main() {Math m;function<int(int, int)> f = bind(&Math::Minus<int>, &m, placeholders::_1, placeholders::_2);cout << f(1, 2) << endl; // -1return 1; }
std::cunction() 简单描述相关推荐
- sas简单描述统计分析和散点图
简单描述统计分析 一. means过程 (一)例题和语句分析 例题1:某车间有30个人分成4组,求车间工人平均每小时制作的配件个数 data data3_1; input no w n; /*按自由格 ...
- TCP/IP 协议标准简单描述
TCP/IP 协议标准简单描述 说明 分为三部分:中文名称.缩写.说明. 应用层 DNS 域名服务 (DNS) 功能: 将域名转化为IP地址 BOOTP 引导程序协议 (BOOTP) 功能: 允许无盘 ...
- 如果你要实现IOC,请简单描述一下实现步骤?
如果你要实现IOC,请简单描述一下实现步骤? 实现IOC的步骤: ①定义用来描述bean的配置的Java类. ②解析bean的配置,将bean的配置信息转换为BeanDefinition对象保存到内存 ...
- Linux主要的系统目录及其简单描述
Linux主要的系统目录及其简单描述如下: /sbin: 一般存放非普通用户使用的命令(有时普通用户也可能会用到).目录/usr/sbin中也包括了许多系统命令. /etc:系统的配置文件. /roo ...
- 简单描述下微信小程序的相关文件类型?
简单描述下微信小程序的相关文件类型? 微信小程序项目结构主要有四个文件类型,如下: .WXML 是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构.内部主要是微信自己定义的一套组件 ...
- 02 食尚年华石锅土鲫鱼需求简单描述
02 食尚年华石锅土鲫鱼需求简单描述 文章目录 02 食尚年华石锅土鲫鱼需求简单描述 现有情况简述 店主希望实现功能 现有情况简述 食尚年华石锅土鲫鱼是一家餐饮店,目前店内经营采用纯人工方式,顾客进入 ...
- 常用HTML标签的英文全称及简单描述
常用HTML标签的英文全称及简单描述 HTML标签 英文全称 中文释义 a Anchor 锚 abbr Abbreviation 缩写词 acronym Acronym 取首字母的缩写词 addres ...
- 带复选框和简单描述的Qt QTreeWidget树形控件的简单使用
Qt QTreeWidget树形控件的简单使用 具有选择框的树形控件 具有选择框的树形控件 效果:当选中顶层的树形节点时,子节点全部被选中:当取消选中顶层树形节点时,子节点全部被取消:当选中子节点时, ...
- Window布局参数简单描述
Window 布局参数简单描述 文章目录 一.LayoutParams.type 二.LayoutParams.flags 三.Gravity.dimAmount.buttonBrightness.A ...
最新文章
- linux 增加回环设备,linux命令练习:mount fdisk swap dd创建本地回环设备
- php$pat,PHP的Session管理框架 patSession | 码农软件 - 码农网
- 从古希腊神话说起,讲讲英语里的偏旁部首
- 应用Java程序片段动态生成下拉列表
- C++STL常用算术生成算法
- 文房四宝用计算机取代的什么,《文房四宝》阅读练习及答案
- Effective Java(一)———— 代替构造器和Setter的构建器模式
- [收藏] C#面试基础问题
- 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0...
- Cinesamples CineOrch for Mac(电影管弦乐队音色库)v2.0特别版
- 制衣软件测试自学,服装检验作业指导书.doc
- 计算机辅助设计和制造论文,计算机辅助设计与制造CAD-CAM
- 使用AudioRecord实现声音采集
- 用Python制作模拟人生4 Mod(01)
- mysql数据模型三要素_数据模型的作用及三要素是什么?
- IT“茫一代”转型记:创业维艰 苦乐皆有
- android高德地图关键字搜索,关键字搜索-POI搜索-示例中心-JS API 示例 | 高德地图API...
- 微信开发 没有认证过的服务号怎么办?微信提供了测试号(开通了认证过的服务号的功能)
- Springboot综合案例锦集
- 数据库系统概念 第三章 SQL介绍
热门文章
- RT-Thread 模拟器 simulator 搭建 LVGL 的开发调试环境
- 音乐机器人特奥_意大利机器人特奥·特罗尼科征服中国观众 Il Robot italiano conquista la Cina...
- 作业1:关于使用python中scikit-learn(sklearn)模块,实现鸢尾花(iris)相关数据操作(数据加载、标准化处理、构建聚类模型并训练、可视化、评价模型)
- lisp 焊缝标注_基于ObjectARX的焊接符号标注系统开发
- HUAWEI华为MateBook X Pro 2020 i7 16GB+512GB (MACHC-WAE9LP)原装出厂系统恢复原厂系统(送解压密码)
- 学计算机的人c语言修仙评价,评《C语言修仙》 非渊静者 评《C语言修仙》 时间:2019-05-04 11:55:19...
- unhandled system error, NCCL version 2.7.8
- 1191 家谱树(拓扑排序)
- kubeadm 方式搭建k8s笔记
- MVC中集成Hangfire定时任务