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; }
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::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能夠組合多個函數,假設要找出集合中大於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);