一 仿函数配接器种类:
(1)对返回值进行逻辑否定:not1,not2。
(2)对参数进行绑定:bind1st,bind2st。
(3) 用于函数合成:compose1,compose2。
(4)用于函数指针:ptr_fun。
(5)用于成员函数指针:mem_fun、mem_fun_ref。
如下图:
二 对返回值进行否定:
(1)源代码:
1. not1:
template <class _Predicate>
class unary_negate
: public unary_function<typename _Predicate::argument_type, bool>
{
protected:
_Predicate _M_pred;
public:
explicit
unary_negate(const _Predicate& __x) : _M_pred(__x) {}
bool
operator()(const typename _Predicate::argument_type& __x) const
{ return !_M_pred(__x); }
};
//辅助函数
template <class _Predicate>
inline unary_negate<_Predicate>
not1(const _Predicate& __pred)
{ return unary_negate<_Predicate>(__pred); }
2. not2:
template <class _Predicate>
class binary_negate
: public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type,
bool>
{
protected:
_Predicate _M_pred;
public:
explicit
binary_negate(const _Predicate& __x)
: _M_pred(__x) { }
bool
operator()(const typename _Predicate::first_argument_type& __x,
const typename _Predicate::second_argument_type& __y) const
{ return !_M_pred(__x, __y); }
};
//辅助函数
template <class _Predicate>
inline binary_negate<_Predicate>
not2(const _Predicate& __pred)
{ return binary_negate<_Predicate>(__pred); }
(2)使用方法:
struct display
{
void operator()(const int &data)
{
if(not2(less<int>())(data,4))//使用辅助函数
//if(binary_negate<less<int> >(less<int>())(data,4))//直接使用类。
cout<<data<<endl;
}
};
int main()
{
int array[]={1,2,3,4,5,6};
vector<int> vec(array,array+6);
for_each(vec.begin(),vec.end(),display());//输出456.
}
三 对参数进行绑定:bind1st、bind2nd。(STL不支持三元仿函数)
(1)源代码:
1.bind1nd
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); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::second_argument_type& __x) const
{ return op(value, __x); }
};
//辅助函数
template <class _Operation, class _Tp>
inline binder1st<_Operation>
bind1st(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::first_argument_type _Arg1_type;
return binder1st<_Operation>(__fn, _Arg1_type(__x));
}
(2)bind2nd:
template <class _Operation>
class binder2nd
: public unary_function<typename _Operation::first_argument_type,
typename _Operation::result_type>
{
protected:
_Operation op;
typename _Operation::second_argument_type value;
public:
binder2nd(const _Operation& __x,
const typename _Operation::second_argument_type& __y)
: op(__x), value(__y) {}
typename _Operation::result_type
operator()(const typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
};
//辅助函数
template <class _Operation, class _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
(2)使用方法:
struct display
{
void operator()(const int &data)
{
if(bind2nd(less<int>(),4)(data))
cout<<data<<endl;
}
};
int main()
{
int array[]={1,2,3,4,5,6};
vector<int> vec(array,array+6);
for_each(vec.begin(),vec.end(),display());//输出123.
}
四 用于函数合成:compose1和compose2(未纳入STL标准)
(1)源代码:
五 用于函数指针:ptr_fun
这种配接器允许我们将一般函数当做仿函数使用。一般函数无配接能力,所以需要使用ptr_fun进行包装。
源代码如下:
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); }
};
//辅助函数
template <class _Arg, class _Result>
inline pointer_to_unary_function<_Arg, _Result>
ptr_fun(_Result (*__x)(_Arg))
{ return pointer_to_unary_function<_Arg, _Result>(__x); }
/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
template <class _Arg1, class _Arg2, class _Result>//二元仿函数
class pointer_to_binary_function
: public binary_function<_Arg1, _Arg2, _Result>
{
protected:
_Result (*_M_ptr)(_Arg1, _Arg2);
public:
pointer_to_binary_function() {}
explicit
pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2))
: _M_ptr(__x) {}
_Result
operator()(_Arg1 __x, _Arg2 __y) const
{ return _M_ptr(__x, __y); }
};
/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink.
template <class _Arg1, class _Arg2, class _Result>
inline pointer_to_binary_function<_Arg1, _Arg2, _Result>//辅助函数
ptr_fun(_Result (*__x)(_Arg1, _Arg2))
{ return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); }
/** @} */
六 用于成员函数指针:men_fun和men_fun_ref.
(1)源代码如下:
* There are a total of 16 = 2^4 function objects in this family.
* (1) Member functions taking no arguments vs member functions taking
* one argument.
* (2) Call through pointer vs call through reference.
* (3) Member function with void return type vs member function with
* non-void return type.
* (4) Const vs non-const member function.
*
* Note that choice (3) is nothing more than a workaround: according
* to the draft, compilers should handle void and non-void the same way.
* This feature is not yet widely implemented, though. You can only use
* member functions returning void if your compiler supports partial
* specialization.
*
* All of this complexity is in the function objects themselves. You can
* ignore it by using the helper function mem_fun and mem_fun_ref,
* which create whichever type of adaptor is appropriate.
*
* @{
*/
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
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)();
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp>
class const_mem_fun_t : public unary_function<const _Tp*, _Ret>
{
public:
explicit
const_mem_fun_t(_Ret (_Tp::*__pf)() const)
: _M_f(__pf) {}
_Ret
operator()(const _Tp* __p) const
{ return (__p->*_M_f)(); }
private:
_Ret (_Tp::*_M_f)() const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp>
class mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
public:
explicit
mem_fun_ref_t(_Ret (_Tp::*__pf)())
: _M_f(__pf) {}
_Ret
operator()(_Tp& __r) const
{ return (__r.*_M_f)(); }
private:
_Ret (_Tp::*_M_f)();
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp>
class const_mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
public:
explicit
const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const)
: _M_f(__pf) {}
_Ret
operator()(const _Tp& __r) const
{ return (__r.*_M_f)(); }
private:
_Ret (_Tp::*_M_f)() const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp, class _Arg>
class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret>
{
public:
explicit
mem_fun1_t(_Ret (_Tp::*__pf)(_Arg))
: _M_f(__pf) {}
_Ret
operator()(_Tp* __p, _Arg __x) const
{ return (__p->*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg);
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp, class _Arg>
class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret>
{
public:
explicit
const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) {}
_Ret
operator()(const _Tp* __p, _Arg __x) const
{ return (__p->*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg) const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp, class _Arg>
class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
public:
explicit
mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg))
: _M_f(__pf) {}
_Ret
operator()(_Tp& __r, _Arg __x) const
{ return (__r.*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg);
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Ret, class _Tp, class _Arg>
class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
public:
explicit
const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) {}
_Ret
operator()(const _Tp& __r, _Arg __x) const
{ return (__r.*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg) const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp>
class mem_fun_t<void, _Tp> : public unary_function<_Tp*, void>
{
public:
explicit
mem_fun_t(void (_Tp::*__pf)())
: _M_f(__pf) {}
void
operator()(_Tp* __p) const
{ (__p->*_M_f)(); }
private:
void (_Tp::*_M_f)();
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp>
class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*, void>
{
public:
explicit
const_mem_fun_t(void (_Tp::*__pf)() const)
: _M_f(__pf) {}
void
operator()(const _Tp* __p) const
{ (__p->*_M_f)(); }
private:
void (_Tp::*_M_f)() const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp>
class mem_fun_ref_t<void, _Tp> : public unary_function<_Tp, void>
{
public:
explicit
mem_fun_ref_t(void (_Tp::*__pf)())
: _M_f(__pf) {}
void
operator()(_Tp& __r) const
{ (__r.*_M_f)(); }
private:
void (_Tp::*_M_f)();
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp>
class const_mem_fun_ref_t<void, _Tp> : public unary_function<_Tp, void>
{
public:
explicit
const_mem_fun_ref_t(void (_Tp::*__pf)() const)
: _M_f(__pf) {}
void
operator()(const _Tp& __r) const
{ (__r.*_M_f)(); }
private:
void (_Tp::*_M_f)() const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp, class _Arg>
class mem_fun1_t<void, _Tp, _Arg> : public binary_function<_Tp*, _Arg, void>
{
public:
explicit
mem_fun1_t(void (_Tp::*__pf)(_Arg))
: _M_f(__pf) {}
void
operator()(_Tp* __p, _Arg __x) const
{ (__p->*_M_f)(__x); }
private:
void (_Tp::*_M_f)(_Arg);
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp, class _Arg>
class const_mem_fun1_t<void, _Tp, _Arg>
: public binary_function<const _Tp*, _Arg, void>
{
public:
explicit
const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) {}
void
operator()(const _Tp* __p, _Arg __x) const
{ (__p->*_M_f)(__x); }
private:
void (_Tp::*_M_f)(_Arg) const;
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp, class _Arg>
class mem_fun1_ref_t<void, _Tp, _Arg>
: public binary_function<_Tp, _Arg, void>
{
public:
explicit
mem_fun1_ref_t(void (_Tp::*__pf)(_Arg))
: _M_f(__pf) {}
void
operator()(_Tp& __r, _Arg __x) const
{ (__r.*_M_f)(__x); }
private:
void (_Tp::*_M_f)(_Arg);
};
/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink.
template <class _Tp, class _Arg>
class const_mem_fun1_ref_t<void, _Tp, _Arg>
: public binary_function<_Tp, _Arg, void>
{
public:
explicit
const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const)
: _M_f(__pf) {}
void
operator()(const _Tp& __r, _Arg __x) const
{ (__r.*_M_f)(__x); }
private:
void (_Tp::*_M_f)(_Arg) const;
};
// Mem_fun adaptor helper functions. There are only two:
// mem_fun and mem_fun_ref.
template <class _Ret, class _Tp>
inline mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*__f)())
{ return mem_fun_t<_Ret, _Tp>(__f); }
template <class _Ret, class _Tp>
inline const_mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*__f)() const)
{ return const_mem_fun_t<_Ret, _Tp>(__f); }
template <class _Ret, class _Tp>
inline mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*__f)())
{ return mem_fun_ref_t<_Ret, _Tp>(__f); }
template <class _Ret, class _Tp>
inline const_mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*__f)() const)
{ return const_mem_fun_ref_t<_Ret, _Tp>(__f); }
template <class _Ret, class _Tp, class _Arg>
inline mem_fun1_t<_Ret, _Tp, _Arg>
mem_fun(_Ret (_Tp::*__f)(_Arg))
{ return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
template <class _Ret, class _Tp, class _Arg>
inline const_mem_fun1_t<_Ret, _Tp, _Arg>
mem_fun(_Ret (_Tp::*__f)(_Arg) const)
{ return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }
template <class _Ret, class _Tp, class _Arg>
inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
mem_fun_ref(_Ret (_Tp::*__f)(_Arg))
{ return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }
template <class _Ret, class _Tp, class _Arg>
inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const)
{ return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }