1、使用场景

在没有C++11的时候,我们通常使用回调函数来完成某些特定的功能,使用回调函数就需要先声明函数指针

示例:

  1. typedef int(*PFunction)(int);

这里的 PFunction 就是一个函数指针类型,我们可以用它定义函数指针对象,传递到指定位置,用于回调

但C++11的 std::function 出现之后,想要实现上述功能,不再需要函数指针,使用更加简单

使用函数对象需要包含头文件:

  1. #include <functional>

2、函数对象

函数对象通过重载 () 实现

示例:

  1. class MyClass{
  2. public:
  3. int operator()(int a){
  4. return a;
  5. }
  6. }

如上,MyClass 类中重载 () 符号,调用如下:

  1. MyClass myClass;
  2. myClass(12);

myClass 对象就是一个类函数对象

示例:

  1. int TestFunction(int num){
  2. cout<<num<<endl;
  3. }
  4. int TestFunction2(int num){
  5. cout<<num+1<<endl;
  6. }
  7. std::function<int(int)> fun;
  8. fun = TestFunction;
  9. fun(22);//22
  10. fun = TestFunction2;
  11. fun(22);//23

如上,fun 对象就是一个函数对象,它的返回值是 int,需要一个 int 类型的参数

std::function 也可以用在 lambda 上

  1. auto lambda = [](int num, const string& str) -> int {
  2. cout<<str<<endl;
  3. return num;
  4. }
  5. std::function<int(int, const string&)> func = lambda;
  6. func(12, "aaa");

如上例可以看出,std::function 只是保存了函数,使用时仍然需要调用传参

如果希望传递类成员函数,可以使用STL提供的另一种方法: std::bind

3、std::bind

上面的 std::function 定义函数对象,但是没有绑定函数,也没有绑定参数,std::bind 方法返回一个函数对象,绑定参数和函数

示例:

  1. void Function(int num, const string &str)
  2. {
  3. cout << num << " " << str << endl;
  4. }
  5. auto bind = std::bind(Function, 2, "aa");
  6. bind();//2 aa
  7. bind(3, "cc", 11);//2 aa,不会报错,但是参数无效
  8. //使用参数占位符
  9. auto bind2 = std::bind(Function, placeholders::_1, placeholders::_2);
  10. bind2(3, "cc");//3 cc

上例中,bind 对象绑定了函数 Function,以及两个参数,调用时不需要再次传参。也可以使用stl的占位符来预留参数位置

也可以使用成员函数,但是必须且传递的第一个参数必须是对象指针

示例:

  1. class Test
  2. {
  3. public:
  4. Test(int num)
  5. : num(num)
  6. {}
  7. int Function(int n)
  8. {
  9. cout << num << endl;
  10. return num + n;
  11. }
  12. private:
  13. int num;
  14. };
  15. int main()
  16. {
  17. Test test(12);
  18. auto bind = std::bind(&Test::Function, &test, 9);
  19. auto res = bind();
  20. cout << res << endl;
  21. return 0;
  22. }

输出

  1. 12
  2. 21

4、总结

C++11 的函数对象用在需要使用函数指针的地方,替代之

C++11之函数对象的更多相关文章

  1. C++11多态函数对象包装器

    [C++11多态函数对象包装器] 针对函数对象的多态包装器(又称多态函数对象包装器)在语义和语法上和函数指针相似,但不像函数指针那么狭隘.只要能被调用,且其参数能与包装器兼容的都能以多态函数对象包装器 ...

  2. C++ 11 - STL - 函数对象(Function Object) (下)

    1. 预定义函数对象 C++标准库内含许多预定义的函数对象,也就是内置的函数对象. 你可以充分利用他们,不必自己费心去写一些自己的函数对象. 要使用他们,你只要包含如下头文件 #include < ...

  3. C++ 11 - STL - 函数对象(Function Object) (上)

    1. 定义 在STL中,可以把函数传递给算法,也可以把函数对象传递给算法. 那么,什么是函数对象呢? 我们来看下它的声明: class X { public: // define function c ...

  4. C++ 11 - STL - 函数对象(Function Object) (中)

    我们再来看一个复杂的例子 需求: 我们需要对集合内每个元素加上一个特定的值 代码如下: AddInt.h class AddInt { private: int theValue; // the va ...

  5. C++11用于计算函数对象返回类型的统一方法

    [C++11用于计算函数对象返回类型的统一方法] 模板 std::result_of 被TR1 引进且被 C++11 所采纳,可允许我们决定和使用一个仿函数其回返值的类别.底下,CalculusVer ...

  6. C++11新特性之八——函数对象function

    详细请看<C++ Primer plus>(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html ...

  7. Day 11 函数对象,函数嵌套,作用域,闭包

    函数总结 # 函数的定义:def func(a, b):    print(a, b)    return a + b​​# 函数四个组成部分# 函数名:调用函数的依据,必须的# 函数体:执行函数逻辑 ...

  8. javascript 利用匿名函数对象给你异步回调方法传参数

    先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...

  9. C++11—lambda函数

    [1]lambda表达式语法定义 lambda表达式的语法定义如下: [capture] (parameters) mutable ->return-type {statement}; (1) ...

  10. python 函数对象(函数式编程 lambda、map、filter、reduce)、闭包(closure)

    1.函数对象 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函 ...

随机推荐

  1. 在 Ubuntu 20.04 上安装 Visual Studio Code

    Visual Studio Code 是一个由微软开发的强大的开源代码编辑器.它包含内建的调试支持,嵌入的 Git 版本控制,语法高亮,代码自动完成,集成终端,代码重构以及代码片段功能. Visual ...

  2. 如何在CSDN上如何快速转载博客

    复制粘贴应该是最显而易见的方法,但是不仅会有丢失内容,而且格式也会丢失.要想达到更好的效果,可以从html源码入手. 1.在chrome浏览器中打开要转载的文章,右键选择检查(or使用F12) 2.在 ...

  3. Codeforces Round #623 (Div. 2) A~D题,D题multiset使用

    比赛链接:Here 1315A. Dead Pixel 签到题, 比较四个值 max(max(x, a - 1 - x) * b, a * max(y, b - 1 - y)) 1315B. Home ...

  4. 使用 Sealos 一键部署 Kubernetes 集群

    Sealos 是一款以 Kubernetes 为内核的云操作系统发行版,使用户能够像使用个人电脑一样简单地使用云. 与此同时,Sealos 还提供一套强大的工具,可以便利地管理整个 Kubernete ...

  5. freeswitch on debian docker

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 因为centos系统期限的原因,尝试在debian的docker上使用fs. 环境 docker engine:Version 24 ...

  6. C#设计模式14——模板方法的写法

    模板方法(Template Method)是一种设计模式,它定义了一个操作中的算法的骨架,将某些步骤推迟到子类中实现,从而使得子类可以在不改变算法骨架的情况下重新定义算法的某些步骤. 作用: 使用模板 ...

  7. 解决JedisConnectionException的方法

    使用maven连接redis,报JedisConnectionException错误,如下: 解决方案: 找到对应启动的redis.conf文件 1.设置bind配置,已注释 2.设置protecte ...

  8. 每天学五分钟 Liunx 0110 | 服务篇:守护进程 systemd

    有些进程会在系统上运行较长时间,如前面的 Hello World 程序运行时产生的进程.有些进程运行瞬间就结束了,如执行 ps 命令产生的进程,也有的进程会常驻在内存中,提供相应的服务,这样的进程称为 ...

  9. 《DREEAM Guiding Attention with Evidence for Improving Document-Level Relation Extraction》阅读笔记

    代码   原文地址   预备知识: 1.什么是K-L散度(Kullback-Leibler Divergence)? K-L散度,是一种量化两种概率分布P和Q之间差异的方式,又叫相对熵.在概率学和统计 ...

  10. Angular系列教程之管道

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...