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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM