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);
时间: 2024-10-27 11:10:28

c++11——std::function和bind绑定器的相关文章

C++11 学习笔记 std::function和bind绑定器

一.std::function C++中的可调用对象虽然具有比较统一操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法五花八门.为了统一泛化函数对象,函数指针,引用函数,成员函数的指针的各种操作,让我们可以按更统一的方式写出更加泛化的代码,C++11推出了std::function. std::function是可调用对象的包装器.它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象.通过指定它的模板参数,它可以用统一的方式处理函数,函数对象,函数指针,并允许保存和

C++ 11 std::function std::bind使用

cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码: auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); 2.0内的代码用的不是CC_CALLBACK_1而是menu_selector. CC_CALLBACK系列是3.

C++11 std::function用法(c++常问问题十七)

C++11 std::function用法 直接上代码: 例子1:std::function的感觉就像是函数指针那样有木有 #include <iostream> #include <functional> #include <map> using namespace std; // 普通函数 int add(int i, int j) { return i + j; } //lambda表达式 auto mod = [](int i, int j){return i

C++11中function和bind的用法示例

环境Visual Studio 2012,具体代码如下 #include <iostream> #include <functional> #include <string> void PrintNumber(int num) { std::cout << num << std::endl; } struct Printer { void Print(std::string print_str) { std::cout << prin

std::function&quot;函数&quot;对象包装器

语义: 类模板std::function是可调用对象的包装器,可以包装除了类成员之外的所有可调用对象.包括,普通函数,函数指针,lambda,仿函数.通过指定的模板参数,它可以用统一的方式保存,并延迟执行它们.所谓的延迟执行,就是回调了. 它使得C++对C的兼容性更强了. 常规多态案例: #include <iostream> #include <functional> using namespace std; class Operator { public: virtual in

C++中的仿函数,std::function和bind()的用法

1.仿函数:又叫std::function,是C++中的一个模板类 2.C语言中的函数指针: int  add(int a,int b) { return a+b; } typedef int (*func)(int,int);//给函数类型定义别名 func func1; func1=add;//给函数指针初始化 或者int (*func1)(int,int)=add; 函数指针的好处: 假设有10个函数:add,sub,mul,div,...如果采用普通的switch()  case: sw

c++11特性与cocos2d-x 3.0之std::bind与std::function

昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0内的Label锚点是在ccp(0.5,0.5),而一直3.0rc0是ccp(0,0). 累觉不爱.尽管cocos2d-x改变太快,兼容性一次次的暴露出不足,但是,总归是向好的方向进行.于是下载了3.0来玩玩~ cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码:

C++ lamda、function、bind使用

参考资料: http://blog.csdn.net/augusdi/article/details/11771699 lambda 表达式的简单语法如下:[capture] (parameters) -> return value { body } 其中[capture]可以选择如下的不同形式: 使用示例: function std::function对象是对C++中现有的可调用实体的一种类型安全的包裹,std::function 使用 bind std::bind是这样一种机制,它可以预先把

2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用

1        打开建好的T32  Cocos2dx-3.2的一个项目 2        设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3  设置自适应窗口大小的代码是在上面的代码后面紧接着就添加: glview->setDesignResolutionSize(480,320, ResolutionPolicy::EXACT_FIT); 3        cocos2d-x-3.2项目案例(3.2版本之后都去掉了CC前缀) 4        项目目录结构如下: 编写公共