c++11——std::function和bind綁定器

  c++11中增長了std::function和std::bind,可更加方便的使用標準庫,同時也可方便的進行延時求值。c++

可調用對象

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;
less

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) 
而後進行組合,獲得:
spa

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);
相關文章
相關標籤/搜索