STL中的仿函数(或者叫做函数对象):可以实现类似于函数一样的类型,函数最直接的调用形式就是:返回值 函数名(参数列表),仿函数实现了operator()操作符,使用类似于函数。
同时,STL还为仿函数提供了强大的配接器,也就是适配器Adapters,这些适配器本身也属于仿函数,调用方式同样类似于函数。更进一步,这些适配器可以和仿函数、函数、适配器再进行绑定、组合、适配,完成更加复杂的功能。
这部分应该是STL中最简单的部分,实现也比较简单。另外C++11标准对这部分调整比较大,我们先不考虑。暂且把它作为一个学习template的例子。
#ifndef TESTFUNCTIONAL_H
#define TESTFUNCTIONAL_H
namespace Test{
template<class _Arg, class _Result>
struct unary_function
{
typedef _Arg argument_type;
typedef _Result 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;
};
template<class _Tp>
struct plus : public binary_function<_Tp, _Tp, _Tp>{
_Tp operator()(const _Tp& _x, const _Tp& _y) const { return _x + _y; }
};
template<class _Tp>
struct minus : public binary_function<_Tp, _Tp, _Tp>{
_Tp operator()(const _Tp& _x, const _Tp& _y) const { return _x - _y; }
};
template<class _Tp>
struct multiplies : public binary_function<_Tp, _Tp, _Tp>{
_Tp operator()(const _Tp& _x, const _Tp& _y) const { return _x * _y; }
};
template<class _Tp>
struct divides : public binary_function<_Tp, _Tp, _Tp>{
_Tp operator()(const _Tp& _x, const _Tp& _y) const { return _x / _y; }
};
template<class _Tp>
struct modulus : public binary_function<_Tp, _Tp, _Tp>{
_Tp operator()(const _Tp& _x, const _Tp& _y) const { return _x % _y; }
};
template<class _Tp>
struct negate : public unary_function<_Tp, _Tp>{
_Tp operator()(const _Tp& _x) const { return -_x; }
};
template <class _Tp>
struct equal_to : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; }
};
template <class _Tp>
struct not_equal_to : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; }
};
template <class _Tp>
struct greater : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; }
};
template <class _Tp>
struct less : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
};
template <class _Tp>
struct greater_equal : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; }
};
template <class _Tp>
struct less_equal : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; }
};
template <class _Tp>
struct logical_and : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; }
};
template <class _Tp>
struct logical_or : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; }
};
template <class _Tp>
struct logical_not : public unary_function<_Tp,bool>
{
bool operator()(const _Tp& __x) const { return !__x; }
};
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);
}
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);
}
//绑定一个二元操作符类的第一个操作数,也就是调用operator()参数需要传递第二个操作数
template<class _Operation>
class binder1st : public unary_function<typename _Operation::second_argument_type,//派生自一元操作符类,
//一元操作符的参数类型为该二元操作符类的第二个操作数类型,与需要调用的operator()参数类型一样
typename _Operation::result_type>{
protected:
_Operation _op;
typename _Operation::first_argument_type value;
public:
binder1st(const _Operation& op, const typename _Operation::first_argument_type& _x)
:_op(op), value(_x){}
typename _Operation::result_type operator()(const typename _Operation::second_argument_type& _y) const{
return _op(value, _y);
}
};
template<class _Operation, class _Tp>
inline binder1st<_Operation>
bind1st(const _Operation& op, const _Tp& _x){
typedef typename _Operation::first_argument_type _Arg1_type;
return binder1st<_Operation>(op, _Arg1_type(_x));
}
//绑定一个二元操作符类的第二个操作数,也就是调用operator()参数需要传递第一个操作数
template<class _Operation>
class binder2nd : public unary_function<typename _Operation::first_argument_type,//派生自一元操作符类,
//一元操作符的参数类型为该二元操作符类的第二个操作数类型,与需要调用的operator()参数类型一样
typename _Operation::result_type>{
protected:
_Operation _op;
typename _Operation::second_argument_type value;
public:
binder2nd(const _Operation& op, const typename _Operation::second_argument_type& _y)
:_op(op), value(_y){}
typename _Operation::result_type operator()(const typename _Operation::first_argument_type& _x) const{
return _op(_x, value);
}
};
template<class _Operation, class _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& op, const _Tp& _y)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(op, _Arg2_type(_y));
}
//f(g(x))
template<class _Operation1, class _Operation2>
class unary_compose : public unary_function<typename _Operation2::argument_type,
typename _Operation1::result_type>
{
protected:
_Operation1 _M_op1;
_Operation2 _M_op2;
public:
unary_compose(const _Operation1& op1, const _Operation2& op2)
:_M_op1(op1), _M_op2(op2){}
typename _Operation1::result_type operator()(const typename _Operation2::argument_type & _x) const {
return _M_op1(_M_op2(_x));
}
};
template<class _Operation1, class _Operation2>
inline unary_compose<_Operation1, _Operation2>
compose1(const _Operation1& op1, const _Operation2& op2){
return unary_compose<_Operation1, _Operation2>(op1, op2);
}
//f(g1(x), g2(x))
template<class _Operation1, class _Operation2, class _Operation3>
class binary_compose : binary_function<typename _Operation2::argument_type,
typename _Operation3::argument_type,
typename _Operation1::result_type>
{
protected:
_Operation1 _M_op1;
_Operation2 _M_op2;
_Operation3 _M_op3;
public:
binary_compose(const _Operation1& op1, const _Operation2& op2, const _Operation3& op3)
:_M_op1(op1), _M_op2(op2), _M_op3(op3){}
typename _Operation1::result_type operator()(typename const _Operation2::argument_type& _x) const{
return _M_op1(_M_op2(_x), _M_op3(_x));
}
};
template<class _Operation1, class _Operation2, class _Operation3>
inline binary_compose<_Operation1, _Operation2, _Operation3>
compose2(const _Operation1& op1, const _Operation2& op2, const _Operation3& op3){
return binary_compose<_Operation1, _Operation2, _Operation3>(op1, op2, op3);
}
//普通单参数函数转对象
template<class _Arg, class _Result>
class pointer_to_unary_function : public unary_function<_Arg, _Result>{
protected:
_Result (*_pfn)(_Arg);
public:
pointer_to_unary_function(){}
explicit pointer_to_unary_function(_Result (*pfn)(_Arg)) : _pfn(pfn){}
_Result operator()(_Arg _x) const{
return _pfn(_x);
};
};
template<class _Arg, class _Result>
inline pointer_to_unary_function<_Arg, _Result>
ptr_fun(_Result (*pfn)(_Arg)){
return pointer_to_unary_function<_Arg, _Result>(pfn);
}
//普通2参数函数转对象
template<class _Arg1, class _Arg2, class _Result>
class pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result>
{
protected:
_Result (*_pfn)(_Arg1, _Arg2);
public:
pointer_to_binary_function(_Result (*pfn)(_Arg1, _Arg2))
:_pfn(pfn){}
_Result operator()(_Arg1 _x, _Arg2 _y) const{
return _pfn(_x, _y);
}
};
template<class _Arg1, class _Arg2, class _Result>
inline pointer_to_binary_function<_Arg1, _Arg2, _Result>
ptr_fun(_Result (*pfn)(_Arg1, _Arg2)){
return pointer_to_binary_function<_Arg1, _Arg2, _Result>(pfn);
}
//类函数,类对象指针
template<class _Ret, class _Tp>
class mem_fun_t : public unary_function<_Tp*, _Ret>{
protected:
_Ret (_Tp::*_pfn)();
public:
explicit mem_fun_t(_Ret (_Tp::*pfn)()) : _pfn(pfn){}
_Ret operator()(_Tp* _p) const{
return (_p->*_pfn)();
}
};
//类const函数,类对象指针
template<class _Ret, class _Tp>
class const_mem_fun_t : public unary_function<const _Tp*, _Ret>{
protected:
_Ret (_Tp::*_pfn)() const;
public:
explicit const_mem_fun_t(_Ret (_Tp::*pfn)() const): _pfn(pfn) {}
_Ret operator()(const _Tp* _p) const{
return (_p->*_pfn)();
}
};
//类函数,类对象引用
template<class _Ret, class _Tp>
class mem_fun_ref_t : public unary_function<_Tp, _Ret>{
protected:
_Ret (_Tp::*_pfn)();
public:
explicit mem_fun_ref_t(_Ret (_Tp::*pfn)()) : _pfn(pfn){}
_Ret operator()(_Tp& _p) const{
return (_p.*_pfn)();
}
};
//类const函数,类对象引用
template<class _Ret, class _Tp>
class const_mem_fun_ref_t : public unary_function<_Tp, _Ret>{
protected:
_Ret (_Tp::*_pfn)();
public:
explicit const_mem_fun_ref_t(_Ret (_Tp::*pfn)() const) : _pfn(pfn){}
_Ret operator()(const _Tp& _p) const{
return (_p.*_pfn)();
}
};
//含参数省略......
template<class _Ret, class _Tp>
inline mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*pfn)()){
return mem_fun_t<_Ret, _Tp>(pfn);
}
template<class _Ret, class _Tp>
inline const_mem_fun_t<_Ret, _Tp>
mem_fun(_Ret (_Tp::*pfn)() const){
return const_mem_fun_t<_Ret, _Tp>(pfn);
}
template<class _Ret, class _Tp>
inline mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*pfn)()){
return mem_fun_ref_t<_Ret, _Tp>(pfn);
}
template<class _Ret, class _Tp>
inline const_mem_fun_ref_t<_Ret, _Tp>
mem_fun_ref(_Ret (_Tp::*pfn)() const){
return const_mem_fun_ref_t<_Ret, _Tp>(pfn);
}
}
#endif //TESTFUNCTIONAL_H实现方面我写了一部分,一些相似的偷懒省略了,如果想看完整版的可以下载源码。另外,我还对它做了一些测试:
#include "TestFunctional.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
class TestClass{
public:
void testFun() { cout << "testfun" << endl; }
void testFunC() const { cout << "testfun1 const" << endl;}
};
int main(int argc, char *argv[])
{
typedef Test::less<int> Op_less;
int opVal = 6;
int val = 4;
// 6 < x
Test::binder1st<Op_less > bd1 = Test::bind1st<Op_less, double>(Op_less(), opVal);
cout << opVal << " less than " << val << '\t' << boolalpha << bd1(val) << endl;
// x < 6 ,即 6 > x
Test::binder2nd<Op_less > bd2 = Test::bind2nd<Op_less, double>(Op_less(), opVal);
cout << val << " less than " << opVal << '\t' << boolalpha << bd2(val) << endl;
//f(x) = 3 * x, g(x) = x + 2 ==> f(g(x)) = (x + 2) * 3;
typedef Test::plus<int> Op_plus;
typedef Test::multiplies<int> Op_mult;
cout << Test::compose1<Test::binder1st<Op_mult>, Test::binder2nd<Op_plus> >(
Test::bind1st<Op_mult, int>(Op_mult(), 3), Test::bind2nd<Op_plus, int>(Op_plus(), 2))(val) << endl;
//f(x, y) = x * y, g1(x) = x + 2, g2(x) = 6 - x ==>f(g1(x), g2(x)) = (x + 2) * (6 - x)
typedef Test::minus<int> Op_minus;
cout << Test::compose2<Op_mult, Test::binder2nd<Op_plus>, Test::binder1st<Op_minus> >(Op_mult(),
Test::bind2nd<Op_plus, int>(Op_plus(), 2), Test::bind1st<Op_minus, int>(Op_minus(), 6))(val) << endl;
TestClass tc1;
Test::mem_fun(&TestClass::testFun)(&tc1);
Test::mem_fun(&TestClass::testFunC)(&tc1);
system("pause");
return 1;
}
测试结果一并附上吧,我没有在gcc下测试,仅仅是在vs2010中运行了。
原文地址:http://blog.csdn.net/soso101/article/details/40895069