文章目录

  • 1. 可调用对象
    • 实例
  • 2.可调用对象包装器 std::function
    • 实例
      • 1.包装普通函数
      • 2.包装模板函数
      • 3.包装lambda表达式
      • 4. 包装函数对象
        • 非模板类型
        • 模板类型:
      • 5.包装类静态成员函数
        • 非模板类型
        • 模板类型:
      • 6. 包装类对象成员函数
        • 非模板类型:
        • 模板类型:
      • 7. 拷贝、移动

1. 可调用对象

c++中,可调用对象有如下几种定义:

  1. 函数指针
  2. 一个具有operator()成员函数的类对象
  3. 一个可被转换为函数指针的类对象
  4. 一个类成员(函数)指针

实例

  1. 函数指针
void func(void)
{//....
}
  1. 一个具有operator()成员函数的类
struct Foo
{void operator()(void){//...}
}
  1. 一个可被转换为函数指针的类对象
struct Bar
{using fr_t = void(*)(void);static void func(void){//...}operator fr_t(void ){return func;}
};
  1. 一个类成员(函数)指针
struct A
{int a_;void mem_func(void ){//...}
}

调用代码

int main(void)
{void (* func_ptr)(void) = &func;  //1. 函数指针func_ptr();Foo foo;foo();                  //2. 一个具有operator()成员函数的类 仿函数Bar bar;bar();             //一个可被转换为函数指针的类对象void (A::*mem_func_ptr)(void) = &A::mem_func;   //4 类成员函数指针int A::*mem_obj_ptr = &A::a_;             //类成员指针A aa;(aa.*mem_func_ptr)();aa.*mem_obj_ptr = 123;retrun 0;
}

从上述看出,除了类的成员指针调用 aa.*mem_obj_ptr = 123;,其他的调用均可以像一个函数一样做调用操作,即 func_ptr(); foo(); bar(); (aa.*mem_func_ptr)();

所以可调用对象五花八门,当我们试图用统一的方式来保存,或传递一个可调用对象时,会十分繁琐。
由此引入了 std::funcution 和 std::bind,统一了可调用对象的各种操作

2.可调用对象包装器 std::function

std::function是一个函数包装器,该函数包装器模板能包装任何类型的可调用实体,如普通函数,函数对象,lamda表达式等。包装器可拷贝,移动等,并且包装器类型仅仅依赖于调用特征,而不依赖于可调用元素自身的类型。std::function是C++11的新特性,包含在头文件中。

一个std::function类型对象实例可以包装下列这几种可调用实体:函数、函数指针、成员函数、静态函数、lamda表达式和函数对象。std::function对象实例可被拷贝和移动,并且可以使用指定的调用特征来直接调用目标元素。当std::function对象实例未包含任何实际可调用实体时,调用该std::function对象实例将抛出std::bad_function_call异常。

实例

1.包装普通函数

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

2.包装模板函数

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

3.包装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;
}

4. 包装函数对象

非模板类型
#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;
}

5.包装类静态成员函数

非模板类型
#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;
}

6. 包装类对象成员函数

非模板类型:
#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;
}

7. 拷贝、移动


int callback(int p)
{//...return p;
}
int main(int argc, char *argv[]){std::cout << "Hello world" << std::endl;std::function<int(int)> callback2 = callback; //拷贝赋值运算符std::cout << callback2(7) << std::endl;std::function<int(int)>&& callback3 = std::move(callback); //移动赋值运算符std::cout << callback3(7) << std::endl;std::cout << callback(7) << std::endl;std::function<int(int)> callback4(callback); //拷贝std::cout << callback4(7) << std::endl;return 0;
}

c++ std::function相关推荐

  1. 函数指针amp;绑定: boost::functoin/std::function/bind

    see link: https://isocpp.org/wiki/faq/pointers-to-members function vs template: http://stackoverflow ...

  2. C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项

    前言 std::function 作为标准库提供的函数指针,使用起来还是比较方便的,不过在使用过程中有一些需要注意的细节,这里做一个简单的记录. 基本使用 头文件: #include <func ...

  3. C++11中std::function的使用

    类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通函数.Lambda表达式.函数指 ...

  4. std::function简介

    1. 简介 std::function是一个函数对象的包装器,std::function的实例可以存储,复制和调用任何可调用的目标,包括: 函数. lamada表达式. 绑定表达式或其他函数对象. 指 ...

  5. C++——包装器std::function与绑定器std::bind

    C++--包装器std::function与绑定器std::bind 1.可调用对象的包装器 std::function是可调用对象的包装器.它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可 ...

  6. C++11 std::bind std::function 高级用法

    C++11 std::bind std::function 高级用法 (c++11的新特性) 原文:https://blog.csdn.net/yangjie6898862/article/detai ...

  7. C++中std::function和std::bind

    1.可调用对象 可调用对象有一下几种定义: 是一个函数指针,参考 C++ 函数指针和函数类型: 是一个具有operator()成员函数的类的对象: 可被转换成函数指针的类对象: 一个类成员函数指针: ...

  8. callable object与新增的function相关 C++11中万能的可调用类型声明std::function...

    在c++11中,一个callable object(可调用对象)可以是函数指针.lambda表达式.重载()的某类对象.bind包裹的某对象等等,有时需要统一管理一些这几类对象,新增的function ...

  9. C++ 11三个新特性的简单使用 - std::function、lambda 表达式、智能指针

    使用Dev C++:先设置Dev C++ 支持 C++ 11:见此文后部: https://blog.csdn.net/bcbobo21cn/article/details/111466179 1 s ...

  10. C++11 std::function

    @time 2019-07-07 @author Ruo_Xiao 1.头文件 #include <functional> 2.作用 类模版 std::function 是一种通用.多态的 ...

最新文章

  1. 数据结构——线性结构
  2. html word-wrap,CSS3 Word-wrap
  3. hadoop基础教程
  4. 质量故事(4)---割草的男孩
  5. go 依赖注入 哪个好_go与java的依赖注入实现的一些差异
  6. Docker 的出现
  7. linux 6.7 ifcfg eth0,centos 的ifcfg-eth0只有只读权限,怎么修改其内容呢?
  8. initcall机制原理及实践
  9. Nmap局域网主机存活发现
  10. Python百度文库爬虫终极版
  11. 姜汝祥是个骗子吗_我是个骗子你是?
  12. Effective Java 2.0_中英文对照_Item 7
  13. cadence allegro - 四层板设置 ……F
  14. 小程序昵称突然变成了微信用户头像变成了默认
  15. Docker-配置私有仓库
  16. 高仿iReader书架效果
  17. Linux安装NS3
  18. 台达DVP ES系列plc与3台台达MS300变频器通讯程序 实现频率设定,启停控制,实际频率读取等
  19. 应用密码学第一章绪论笔记
  20. 手写数字识别模型识别自己的图片

热门文章

  1. MySQL数据库——day26 数据库安装,卸载,概念,msq的介绍,安装,连接,DDL,DML,DQL模糊查询,字段控制(别名和运算),排序,聚合函数,分组查询(where和having),分页查询
  2. 站长怎样利用好腾讯产品做网站推广
  3. 高级前端进阶:我是如何把 C/C++ 代码跑在浏览器上的?
  4. 程序员如何成长?如何进阶?——一个老程序员的经验分享1
  5. 水果店开在哪位置最好,水果店应开到什么位置
  6. Ms08-067 漏洞利用
  7. 因特网提供的基本服务的计算机,因特网能提供的最基本服务有哪些
  8. 拓扑排序--Kitchen Plates
  9. 数学物理方程与特殊函数—分离变量法
  10. PorterDuffXfermode使用