c++ std::function
文章目录
- 1. 可调用对象
- 实例
- 2.可调用对象包装器 std::function
- 实例
- 1.包装普通函数
- 2.包装模板函数
- 3.包装lambda表达式
- 4. 包装函数对象
- 非模板类型
- 模板类型:
- 5.包装类静态成员函数
- 非模板类型
- 模板类型:
- 6. 包装类对象成员函数
- 非模板类型:
- 模板类型:
- 7. 拷贝、移动
1. 可调用对象
c++中,可调用对象有如下几种定义:
- 函数指针
- 一个具有operator()成员函数的类对象
- 一个可被转换为函数指针的类对象
- 一个类成员(函数)指针
实例
- 函数指针
void func(void)
{//....
}
- 一个具有operator()成员函数的类
struct Foo
{void operator()(void){//...}
}
- 一个可被转换为函数指针的类对象
struct Bar
{using fr_t = void(*)(void);static void func(void){//...}operator fr_t(void ){return func;}
};
- 一个类成员(函数)指针
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相关推荐
- 函数指针amp;绑定: boost::functoin/std::function/bind
see link: https://isocpp.org/wiki/faq/pointers-to-members function vs template: http://stackoverflow ...
- C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项
前言 std::function 作为标准库提供的函数指针,使用起来还是比较方便的,不过在使用过程中有一些需要注意的细节,这里做一个简单的记录. 基本使用 头文件: #include <func ...
- C++11中std::function的使用
类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通函数.Lambda表达式.函数指 ...
- std::function简介
1. 简介 std::function是一个函数对象的包装器,std::function的实例可以存储,复制和调用任何可调用的目标,包括: 函数. lamada表达式. 绑定表达式或其他函数对象. 指 ...
- C++——包装器std::function与绑定器std::bind
C++--包装器std::function与绑定器std::bind 1.可调用对象的包装器 std::function是可调用对象的包装器.它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可 ...
- C++11 std::bind std::function 高级用法
C++11 std::bind std::function 高级用法 (c++11的新特性) 原文:https://blog.csdn.net/yangjie6898862/article/detai ...
- C++中std::function和std::bind
1.可调用对象 可调用对象有一下几种定义: 是一个函数指针,参考 C++ 函数指针和函数类型: 是一个具有operator()成员函数的类的对象: 可被转换成函数指针的类对象: 一个类成员函数指针: ...
- callable object与新增的function相关 C++11中万能的可调用类型声明std::function...
在c++11中,一个callable object(可调用对象)可以是函数指针.lambda表达式.重载()的某类对象.bind包裹的某对象等等,有时需要统一管理一些这几类对象,新增的function ...
- C++ 11三个新特性的简单使用 - std::function、lambda 表达式、智能指针
使用Dev C++:先设置Dev C++ 支持 C++ 11:见此文后部: https://blog.csdn.net/bcbobo21cn/article/details/111466179 1 s ...
- C++11 std::function
@time 2019-07-07 @author Ruo_Xiao 1.头文件 #include <functional> 2.作用 类模版 std::function 是一种通用.多态的 ...
最新文章
- 数据结构——线性结构
- html word-wrap,CSS3 Word-wrap
- hadoop基础教程
- 质量故事(4)---割草的男孩
- go 依赖注入 哪个好_go与java的依赖注入实现的一些差异
- Docker 的出现
- linux 6.7 ifcfg eth0,centos 的ifcfg-eth0只有只读权限,怎么修改其内容呢?
- initcall机制原理及实践
- Nmap局域网主机存活发现
- Python百度文库爬虫终极版
- 姜汝祥是个骗子吗_我是个骗子你是?
- Effective Java 2.0_中英文对照_Item 7
- cadence allegro - 四层板设置 ……F
- 小程序昵称突然变成了微信用户头像变成了默认
- Docker-配置私有仓库
- 高仿iReader书架效果
- Linux安装NS3
- 台达DVP ES系列plc与3台台达MS300变频器通讯程序 实现频率设定,启停控制,实际频率读取等
- 应用密码学第一章绪论笔记
- 手写数字识别模型识别自己的图片
热门文章
- MySQL数据库——day26 数据库安装,卸载,概念,msq的介绍,安装,连接,DDL,DML,DQL模糊查询,字段控制(别名和运算),排序,聚合函数,分组查询(where和having),分页查询
- 站长怎样利用好腾讯产品做网站推广
- 高级前端进阶:我是如何把 C/C++ 代码跑在浏览器上的?
- 程序员如何成长?如何进阶?——一个老程序员的经验分享1
- 水果店开在哪位置最好,水果店应开到什么位置
- Ms08-067 漏洞利用
- 因特网提供的基本服务的计算机,因特网能提供的最基本服务有哪些
- 拓扑排序--Kitchen Plates
- 数学物理方程与特殊函数—分离变量法
- PorterDuffXfermode使用