c++11——std::function和bind绑定器
c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值。
可调用对象
c++中的可调用对象存在以下几类:
(1)函数指针
(2)具有operator()成员函数的类对象(仿函数)
(3)可被转换为函数指针的类对象
(4)类成员(函数)指针
void func(void){
//....
}
struct Foo{
void operator()(void){
//...
}
};
struct Bar{
using fr_t = void(*)(void);
static void func(void){
//...
}
operator fr_t(void){ //可以进行隐式转换,转换结果为 fr_t 为一个函数指针
return func; //operator xxx (void) 函数可以对类的对象进行隐式转换
}
};
struct A{
int a_;
void mem_func(void){
//...
}
};
int main(){
void(* func_ptr)(void) = &func; //1.函数指针
func_ptr();
Foo foo; //2. 仿函数
foo();
Bar bar;
bar(); //可被转化为函数指针的类对象
void (A::*mem_func_ptr)(void) = &A::mem_func; //类成员函数指针
int A::*mem_obj_ptr = &A::a; //类成员指针
return 0;
}
可调用对象包装器——std::function
c++11通过std::function, std::bind统一了可调用对象的各种操作。std::function是可调用对象的包装器,它是一个类模板,可以容纳类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延时执行它们。 std::function<返回值(参数类型)> f;
void func(void){
}
class Foo{
public:
static int foo_func(int a){
std::cout << "hello" <<std::endl;
return a;
}
};
int main(){
std::function<void(void)> f;
f = func;
std::function<int(int)> = Foo::foo_func;
return 0;
}
std::bind绑定器
std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用 std::function进行保存,并延迟调用到任何我们需要的时候。它主要有两大作用:
(1)将可调用对象与其参数一起绑定成一个仿函数
(2)将多元(参数个数为n>1)可调用对象转成x元( 0 <= 0 <= n)元可调用对象,即只绑定部分参数。
(3)使用bind可以将类的非静态成员函数绑定起来,赋值给一个可执行std::function对象
#include<functional>
using namespace std; int func(int a, int b){
std::cout << "a = " << a << ", b = " << b << std::endl;
return a + b;
} class A{
public:
int mem_func(int a, int b){
std::cout << "a = " << a << ", b = " << b << std::endl;
return a + b;
}
};
int main(){
//直接生成一个可调用对象,然后调用,参数为3
//bind(func, 1, std::placeholders::_1)中表示将参数1 和参数 std::placeholders::_1作为函数func的参数,绑定成另一个可执行对象。
//在绑定的时候, 按照顺序,1 作为 func(int a, int b) 中形参a的实参; std::placeholders::_1 作为 func(int a, int b) 中形参b的实参 //std::placeholders::_1 是占位符,表示将绑定后得到的可执行对象进行调用的时候,实参的第1个,放到 std::placeholders::_1的位置上去
//依次,std::placeholders::_2 将调用的时候实参的第2个,放到该位置上去
//注意,占位符 std::placeholders::_x 中x必须小于等于调用的时候实际参数的个数!!
std::bind(func, 1, std::placeholders::_1)(3); //输出 a = 1, b = 3
std::bind(func, 1, std::placeholders::_2)(3, 6); //输出 a = 1, b = 6 //用function可调用对象f保存bind后的结果
std::function<int(int)> f = std::bind(func, 1, std::placeholders::_1);
f(2); //输出 a = 1, b = 2
f = std::bind(func, std::placeholders::_1, 1);
f(3); //输出 a = 3, b = 1 //将类的非静态成员函数,以及类的对象实例,进行绑定
A a;
f = std::bind(&A::mem_func, a, 1, std::placeholders::_1);
f(10);
return 0;
}
使用组合bind函数
bind可以组合多个函数,假设要找出集合中大于5小于10的元素个数.
判断一个数是否大于5的闭包,代码std::bind(std::greater< int>(), std::placeholders::_1, 5)
判断一个数是否小于10的闭包,代码std::bind(std::less_equal< int>(), std::placeholders::_1, 10)
然后进行组合,得到:
using std::placeholders::_1;
//查找集合中大于5小于等于10的元素个数
auto f = std::bind(
std::logic_and<bool>(),
std::bind(std::greater<int>(), _1, 5),
std::bind(std::less_equal<int>(), _1, 10)); int count = std::count_if(coll.begin(), coll.end(), f);
c++11——std::function和bind绑定器的更多相关文章
- C++11 学习笔记 std::function和bind绑定器
C++11 学习笔记 std::function和bind绑定器 一.std::function C++中的可调用对象虽然具有比较统一操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法 ...
- 第11课 std::bind和std::function(2)_std::bind绑定器
1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...
- C++ 11 std::function std::bind使用
cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码: auto closeItem = MenuItemImage::create( "CloseNorm ...
- C++11 std::function、std::bind和lambda表达式
参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ...
- C/C++ C++ 11 std::function和std::bind用法
std::bind() std::bind 主要用于绑定生成目标函数,一般用于生成的回调函数,cocos的回退函数都是通过std::bind和std::function实现的.两个点要明白: 1.绑定 ...
- 利用C++11的function和bind简化类创建线程
问题引出 当在类中需要创建线程时,总是因为线程函数需要定义成静态成员函数,但是又需要访问非静态数据成员这种需求,来做若干重复性的繁琐工作.比如我以前就经常定义一个静态成员函数,然后定一个结构体,结构体 ...
- C++11 中function和bind以及lambda 表达式的用法
关于std::function 的用法: 其实就可以理解成函数指针 1. 保存自由函数 void printA(int a) { cout<<a<<endl; } std:: ...
- C++中的仿函数,std::function和bind()的用法
1.仿函数:又叫std::function,是C++中的一个模板类 2.C语言中的函数指针: int add(int a,int b) { return a+b; } typedef int (*f ...
- C++11 std::function用法
转自 http://www.hankcs.com/program/cpp/c11-std-function-usage.html function可以将普通函数,lambda表达式和函数对象类统一起来 ...
随机推荐
- 【JS】通过JS实现超市小票打印功能——ActiveX控件
应客户的需求= = ,要在网页端实现打印小票的功能 先来一张打印出的小票效果图(合计明显不对,因为有修改订单功能,请各位忽略) 用什么方法实现呢: 我想应该是有三种吧 1.用第三方的浏览器控件(这个好 ...
- 【Unity】物体跟随鼠标移动
需求:2D游戏中,需要物体跟随鼠标移动. 做法:其实思路也很简单,就是先获取到鼠标的坐标,然后赋值给目标物体即可. void Update(){ // 物体跟随鼠标移动 Vector2 mousePo ...
- java.lang.OutOfMemoryError: Java heap space 解决方法
从网上抄过来的,因为经常碰到这个问题,记录一下. java.lang.OutOfMemoryError: Java heap space 解决方法 这个问题的根源是jvm虚拟机的默认Heap大小是64 ...
- android 相机拍照后选择照片编辑,相片编辑界面直线形状会显示锯齿状
因为 decode 出来的图片太小,小于屏幕.所以,显示的时候 会把图片略微放大,导致直线形状会显示锯齿状. 能够改动getScreenImageSize 方法中的size 的大小,比方能够把13 ...
- iOS边练边学--九宫格布局
一.介绍一下ViewController中的结构 二.九宫格设计思路 三.代码实现 // 点击增加按钮 - (void)add:(UIButton *)btn { // 定义一行中的列数(个数) NS ...
- 验证url 地址是否是图片
由于正则不是很熟悉 所以面对这样的目前只能采取两步走 一 判断url地址是否是正确的http 二判断后缀是否是图片 格式 /驗證URL function validUrl(strUrl){ strUr ...
- JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比
1.什么是JVM? JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才能够运行Java程序,JAVA在编译后会生成类似于汇编语言的JVM字节码,与C语言编译后产生的汇编语言不同的是, ...
- 用 #include <filename.h> 格式来引用标准库的头文件
用 #include <filename.h> 格式来引用标准库的头文件(编译器将从 标准库目录开始搜索). #include <iostream> /* run this p ...
- 标准的 C++ 由三个重要部分组成
标准的 C++ 由三个重要部分组成: 核心语言,提供了所有构件块,包括变量.数据类型和常量,等等.C++ 标准库,提供了大量的函数,用于操作文件.字符串等.标准模板库(STL),提供了大量的方法,用于 ...
- android2.2应用开发之IccCard(sim卡或USIM卡)(转至 http://www.2cto.com/kf/201306/223784.html)
如果要做android通讯录的联系人的机卡混排显示,由于手机卡类型的不同,导致手机卡存储容量以及可以存储信息不同,就要涉及到android去读Icc卡的信息. 一般的sim卡只能存储姓名跟一个电话号码 ...