std::function用法详解

代码在:VCCommon/functionDemo

std::function 简介

类模板 std :: function 是一个通用的多态函数包装器。 std :: function 的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。当std::function对象未包裹任何实际的可调用元素,调用该 std::function 对象将抛出std::bad_function_call 异常。

与函数指针的比较

#include<iostream>
#include <functional>using namespace std;// c type global function
int c_func(int a, int b)
{return a + b;
}int main()
{typedef int(*Func)(int ,int);Func f1 = c_func;cout<< f1(1,2)<<endl;  //3std::function<int(int, int)>f2 = c_func;cout<<f2(1, 2)<<endl;      // 3system("pause");return 0;
}

从上面我们可以看出,使用C++11的function类调用函数方便多了。

function 类模板

template< class R, class... Args >
class function<R(Args...)>;

模板参数说明:

  • R: 被调用函数的返回类型
  • Args…:被调用函数的形参

例如:function<int(int,int)> func;
则 function 类的实例 func 可以指向返回值为int型,有两个形参都为int型的函数。

function 的成员函数

虽然是function是类模板,但其只有成员函数,无数据成员。

成员函数声明 说明
constructor 构造函数:constructs a new std::function instance
destructor 析构函数: destroys a std::function instance
operator= 给定义的function对象赋值
operator bool 检查定义的function对象是否包含一个有效的对象
operator() 调用一个对象

用法

1.调用普通函数

非模板

#include <functional>
#include <iostream>int f(int a, int b)
{return a+b;
}int main()
{std::function<int(int, int)>func = f;cout<<func(1, 2)<<endl;      // 3system("pause");return 0;
}

有模板

#include <functional>
#include <iostream>template<class T>
T f(T a, T b)
{return a+b;
}int main()
{std::function<int(int, int)>func = f<int>;cout<<func(1, 2)<<endl;      // 3system("pause");return 0;
}

2.调用函数对象

非模板

#include<iostream>
#include <functional>using namespace std;//function object
struct functor  // or class functor
{
public:int operator() (int a, int b){return a + b;}
};int main()
{functor ft;function<int(int,int)> func = ft();cout<<func(1,2)<<endl;    //3system("pause");return 0;
}

有模板

#include<iostream>
#include <functional>using namespace std;//function object
template<class T>
struct functor   // or class functor
{
public:T operator() (T a, T b){return a + b;}
};int main()
{functor<int> ft;function<int(int,int)> func = ft;//function<int(int,int)> func = functor<int>();cout<<func(1,2)<<endl;    //3system("pause");return 0;
}

3.调用lambda表达式

#include <functional>
#include <iostream>using namespace std;int main()
{auto f = [](const int a, const int b) { return a + b; };std::function<int(int, int)>func = f;cout << func(1, 2) << endl;      // 3system("pause");return 0;
}

4.调用类静态成员函数

非模板

#include <iostream>
#include <functional>
using namespace std;class Plus
{
public:static int plus(int a, int b){return a + b;}
};int main()
{function<int(int, int)> f = Plus::plus;//function<int(int, int)> f = &Plus::plus;cout << f(1, 2) << endl;     //3system("pause");                                       return 0;
}

有模板

#include <iostream>
#include <functional>
using namespace std;class Plus
{
public:template <class T>static T plus(T a, T b){return a + b;}
};int main()
{function<int(int, int)> f = Plus::plus<int>;//function<int(int, int)> f = &Plus::plus<int>;cout << f(1, 2) << endl;     //3system("pause");                                       return 0;
}

5.调用类成员函数

非模板

#include <iostream>
#include <functional>using namespace std;class Plus
{
public:int plus(int a, int b){return a + b;}
};int main()
{Plus p;function<int(Plus&,int, int)> f = &Plus::plus;function<int(Plus,int, int)> f2 = &Plus::plus;cout << f(p,1, 2) << endl;     //3cout << f2(p,1, 2) << endl;     //3system("pause");                                       return 0;
}

有模板

#include <iostream>
#include <functional>using namespace std;class Plus
{
public:template <class T>T plus(T a, T b){return a + b;}
};int main()
{Plus p;function<int(Plus&,int, int)> f = &Plus::plus<int>;function<int(Plus,int, int)> f2 = &Plus::plus<int>;cout << f(p,1, 2) << endl;      //3cout << f2(p,1, 2) << endl;     //3system("pause");                                       return 0;
}

6.调用类公有数据成员

非模板

#include <iostream>
#include <functional>
using namespace std;class Plus
{
public:Plus(int num_):num(num_){}int  num;
};int main()
{Plus p(2);function<int(Plus&)> f = &Plus::num;function<int(Plus)> f2 = &Plus::num;cout << f(p) << endl;     //2cout << f2(p) << endl; system("pause");                                       return 0;
}
#include <iostream>
#include <functional>using namespace std;template <class T>
class Plus
{
public:Plus(T num_):num(num_){}T  num;
};int main()
{Plus<int> p(2);function<int(Plus<int>&)> f = &Plus<int>::num;function<int(Plus<int>)> f2 = &Plus<int>::num;cout << f(p) << endl;      //2cout << f2(p) << endl;     //2system("pause");                                       return 0;
}

7.通过bind函数调用类成员函数

非模板

#include <iostream>
#include <functional>
using namespace std;class Plus
{
public:int plus(int a, int b){return a + b;}
};class Plus2
{
public:static int plus(int a, int b){return a + b;}
};int main()
{Plus p;// 指针形式调用成员函数function<int(int, int)> f1 = bind(&Plus::plus, &p, placeholders::_1, placeholders::_2);// placeholders::_1是占位符// 对象形式调用成员函数function<int(int, int)> f2 = bind(&Plus::plus, p, placeholders::_1, placeholders::_2);// placeholders::_1是占位符cout << f1(1, 2) << endl;     //3cout << f2(1, 2) << endl;     //3Plus2 p2;// 指针形式调用成员函数function<int(int, int)> f3 = bind(Plus2::plus, placeholders::_1, placeholders::_2);// placeholders::_1是占位符cout << f3(1, 2) << endl;     //3system("pause");                                       return 0;
}

有模板

#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;
}

最后附上一段代码:

#include <iostream>
#include <map>
#include <functional>using namespace std;// 普通函数
int add(int i, int j) { return i + j; }// lambda表达式
auto mod = [](int i, int j){return i % j; };// 函数对象类
struct divide
{int operator() (int denominator, int divisor){return denominator / divisor;}
};int main()
{map<char, function<int(int, int)>> binops = {{ '+', add },{ '-', [](int i, int j){return i - j; } },{ '/', divide() }};cout << binops['+'](10, 5) << endl;cout << binops['-'](10, 5) << endl;cout << binops['/'](10, 5) << endl;system("pause");return 0;
}

该文章持续更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

std::function用法详解相关推荐

  1. 转: std::string用法详解

    原文地址为: 转: std::string用法详解  C++中的string 类 简单介绍 前言: string 的角色 1 string 使用 1.1 充分使用string 操作符 1.2 眼花缭乱 ...

  2. 【C++】C++11的std::function和std::bind用法详解

    在设计回调函数的时候,无可避免地会接触到可回调对象.在C++11中,提供了std::function和std::bind两个方法来对可回调对象进行统一和封装. 可调用对象 C++中有如下几种可调用对象 ...

  3. C++ lambda表达式 std::function 深层详解

    原文: <Under the hood of lambdas and std::function> 本文是根据原文的翻译. 文章目录 什么是lambda? lambda的使用语法 按值捕获 ...

  4. [转] boost::function用法详解

    http://blog.csdn.net/benny5609/article/details/2324474 要开始使用 Boost.Function, 就要包含头文件 "boost/fun ...

  5. boost::function用法详解

    要开始使用 Boost.Function, 就要包含头文件 "boost/function.hpp", 或者某个带数字的版本,从 "boost/function/func ...

  6. C++ std::mutex 用法详解

    Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 头文件中,所以如果你需要使用 std::mutex,就必须包含 头文件. 头文件介绍 Mutex 系列类(四 ...

  7. C++/C--unordered_map常见用法详解

    文章目录 1. std::unordered_map 的定义与特性 2. 构造 std::unordered_map 3. 赋值操作 4. 迭代器操作 4.1 指向整个容器中的元素 4.2 指向某个桶 ...

  8. C++中的unordered_map常见用法详解

    文章目录 1. std::unordered_map 的定义与特性 2. 构造 std::unordered_map 3. 赋值操作 4. 迭代器操作 4.1 指向整个容器中的元素 4.2 指向某个桶 ...

  9. CreateThread用法详解

    CreateThread用法详解 今天我给大家讲一讲C++中的多线程编程技术,C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面 ...

最新文章

  1. Qt 第二章 创建对话框--纯代码实现改变形状的对话框(二)
  2. jwebsocket
  3. java 登陆系统设计_Java 程序设计——登录系统
  4. android listview局部刷新和模拟应用下载
  5. 2021年山东省安全员C证最新解析及山东省安全员C证证考试
  6. 221.Beta多样性PCoA和NMDS排序
  7. JS常用字符串方法复习
  8. 关于提升短信ROI,我的6点思考
  9. 【代码重构(Refectoring)系列教程】基本型别偏执(Primitive Obsession)
  10. 计算机会议论文EI检索,ei检索会议论文算期刊_ei论文检索_ei会议论文算核心吗...
  11. 记录一次teamview无法远程连接对方teamview的过程
  12. hadoop 文本统计一个字符的个数_hadoop统计单词个数 - 卡饭网
  13. elementplus 上传文件
  14. 个人隐私保护条例_个人信息保护及隐私政策
  15. (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  16. 从申请到调用:空号检测 API 使用教程
  17. python爬淘宝商品销量信息_Python爬取淘宝商品价格销量信息
  18. 河北省石家庄市谷歌卫星地图下载
  19. Linux Shell脚本 Linux C程序 获取指定的范围内 or 系统可用端口
  20. 【Android】用户登录界面功能实现:登陆跳转、退出

热门文章

  1. 星梦缘陈彦妃_星梦缘里的林思彤陈彦妃怀孕 陈彦妃老公是谁大曝光
  2. 经典回溯算法(八皇后问题)详解
  3. 视频监控安卓App客户端--Mjpg-streamer推流的播放
  4. 什么是 Hudi Timeline (时间线)
  5. 新媒体月薪4.5万?看完人民日报的招聘我傻了
  6. 一个保险柜密码是三位数,对上其中两位就可以打开,最坏至少试多少次才能保证打开
  7. Python数据类型——序列 (sequence)
  8. Quartz2.2.x官方文档2.2.X—第三章 10.配置,资源使用和SchedulerFactory
  9. 【天赢金创】面向对象的程序设计之创建对象
  10. BZOJ 3982 Stacking Plates 解题报告