更多精彩內容,請關注微信公衆號:後端技術小屋後端
functional functional.h stl_function.h
一元函數對象,是指這類函數對象只接受一個參數並返回一個參數。微信
unary_function
爲STL中全部一元函數對象的基類。它定義了一元函數對象的輸入/輸出參數類型,其中argument_type
爲輸入參數類型,result_type
爲輸出參數類型,這兩種類型由輸入模板參數推導而來。less
template <class _Arg, class _Result> struct unary_function { typedef _Arg argument_type; typedef _Result result_type; };
下面介紹幾種有意思的一元函數對象。ide
binder1st
的功能:將某個參數值綁定到可調用對象(Callable type
,函數對象/函數指針/std::function
)的第一個參數中。同理,binder2nd
將某個參數值綁定到可調用對象的第二個參數中。函數
有了binder1st/binder2nd
,即可利用已有的可調用對象生成各類變體,避免了從新定義帶來的代碼冗餘。源碼分析
auto f = [](double a, double b){ return 2*(a+b); }; double a0 = 1.0; double b0 = 2.0; auto uf1 = std::binder1st(f, a0); auto uf2 = std::binder2nd(f, b0); std::cout << uf1(3.0) << std::endl; // 執行f函數,參數1:被綁定的a0, 參數2: 3.0 std::cout << uf2(4.0) << std::endl; // 執行f函數,參數1: 4.0, 參數2:被綁定的b0
binder1st
內部嵌套了一個可調用對象op
。生成binder1st
對象時,其內部記錄傳入的可調用對象和綁定參數。當執行operator()
時,其調用可調用對象並返回結果。指針
template <class _Operation> class binder1st : public unary_function<typename _Operation::second_argument_type, typename _Operation::result_type> { protected: _Operation op; typename _Operation::first_argument_type value; public: binder1st(const _Operation& __x, const typename _Operation::first_argument_type& __y) : op(__x), value(__y) {} typename _Operation::result_type operator()(const typename _Operation::second_argument_type& __x) const { return op(value, __x); } };
將兩個屬於unary_function
的函數對象級聯。假設函數對象分別爲op1
和op2
, 那麼unary_compose
的執行結果爲op1(op2(x))
。code
所以unary_compose
的輸入參數類型爲_Operation2::argument_type
,輸出參數類型爲_Operation1::result_type
。而且要求在類型上_Operation2::result_type
可隱式轉換成_Operation1::argument_type
。對象
template <class _Operation1, class _Operation2> class unary_compose : public unary_function<typename _Operation2::argument_type, typename _Operation1::result_type> { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); } };
將一個指向一元函數的指針封裝成一元函數對象。繼承
template <class _Arg, class _Result> class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: _Result (*_M_ptr)(_Arg); public: pointer_to_unary_function() {} explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} _Result operator()(_Arg __x) const { return _M_ptr(__x); } };
將類內非靜態成員函數封裝成一元函數對象。
對於mem_fun_t
對象,其構造時記錄指向類_Tp
內非靜態成員函數(輸入參數個數爲零)的指針,執行時,傳入指向_Tp
對象的指針__p
,調用(__p->*_M_f)()
。
在C++中,函數指針相似這種形式:int (*f)(int, double)
,f
指向一個入參爲int, double
,出參爲int
的函數。調用函數指針f
時,只需指定輸入參數。
而成員函數指針相似於:int (T::*mf)(int, double)
,mf
指向一個入參爲int, double
, 出參爲int
的成員函數。調用成員函數指針時,除了需指定輸入參數外,還需指定T
對象指針,由於類中非靜態成員函數是和該類對象綁定的。
template <class _Ret, class _Tp> class mem_fun_t : public unary_function<_Tp*,_Ret> { public: explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)(); };
其餘變體:
const_mem_fun_t
: 將類內非靜態的const成員函數封裝成一元函數對象mem_fun_ref_t
: 相似mem_fun_t
,區別在於調用mem_fun_t
時傳入的是類對象指針,而調用mem_fun_ref_t
時傳入的是類對象引用。const_mem_fun_ref_t
: const_mem_fun_t
和mem_fun_ref_t
的組合negate
: 取負操做。實現中對_Tp
對象執行operator-
操做,所以negate的輸入模板參數不止爲數字,也但是重載了operator-
操做符的其餘任何類型。logical_not
: 邏輯取反。函數對象輸入參數類型爲_Tp
, 輸出參數類型爲bool
。實現中對_Tp
對象執行operator!
操做,對象可重載該操做符。unary_negate
: 同negate
類似,只不過帶了一個判斷條件。輸入參數__x
, 返回布爾值!_M_pred(__x)
。二元函數對象接受兩個參數,返回一個結果值。
STL中定義的全部二元函數對象都繼承自binary_function
, 其中
first_argument_type
: 第一個輸入參數類型second_argument_type
: 第二個輸入參數類型result_type
: 輸出參數類型template <class _Arg1, class _Arg2, class _Result> struct binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; };
同mem_fun_t
相似,將一個成員函數指針封裝成函數對象。區別在於mem_fun_t
中成員函數入參個數爲零,而mem_fun1_t
中成員函數入參個數爲1,這樣的話調用mem_fun1_t
時,需同時傳入成員函數的入參和成員函數所在類對象指針。
其餘變體:const_mem_fun1_t/mem_fun1_ref_t/const_mem_fun1_ref_t
,功能與mem_fun_t
的變體相似,這裏跳過
如下二元函數對象顧名思義,本質上是對各類操做符的封裝。
plus minus multiplies divides modulus equal_to not_equal_to greater less greater_equal less_equal logical_and logical_or logical_not
binary_compose
: 功能同unary_compose
。區別在於將三個二元函數對象級聯,輸出__fn1(__fn2(__x), __fn3(__x))
推薦閱讀
更多精彩內容,請掃碼關注微信公衆號:後端技術小屋。若是以爲文章對你有幫助的話,請多多分享、轉發、在看。