## boost::function的简单实现

2014-12-17 20:35  origins  阅读(...)  评论(...编辑  收藏

## 前言

boost::function和boost:bind是一对强大的利器。相信用过的童鞋多少有些体会。

• 选取比较常见的接收2个参数的情况。
• 支持普通函数/函数指针、成员函数指针。
• 兼容函数对象、函数适配器/boost::bind。

## 实现

template<typename R, typename T1, typename T2>
class base
{
public:
virtual ~base()
{
}

virtual R operator()(T1, T2) = 0;
};

template<typename R, typename T1, typename T2>
class func : public base<R, T1, T2>
{
public:
func(R (*ptr)(T1, T2))
: ptr_(ptr)
{
}

virtual R operator()(T1 a, T2 b)
{
return ptr_(a, b);
}

private:
R (*ptr_)(T1, T2);
};

template<typename R, typename Class, typename T>
class member : public base<R, Class, T>
{
};

template<typename R, typename Class, typename T>
class member<R, Class*, T> : public base<R, Class*, T>
{
public:
member(R (Class::*ptr)(T))
:    ptr_(ptr)
{
}

virtual R operator()(Class* obj, T a)
{
return (obj->*ptr_)(a);
}

private:
R (Class::*ptr_)(T);
};

template<typename T, typename R, typename T1, typename T2>
class functor : public base<R, T1, T2>
{
public:
functor(const T& obj)
: obj_(obj)
{
}

virtual R operator()(T1 a, T2 b)
{
return obj_(a, b);
}

private:
T obj_;
};

template<typename T>
class function
{
};

template<typename R, typename T1, typename T2>
class function<R (T1, T2)>
{
public:
template<typename Class, typename _R, typename _T2>
function(_R (Class::*ptr)(_T2))
: ptr_(new member<R, T1, T2>(ptr))
{
}

template<typename _R, typename _T1, typename _T2>
function(_R (*ptr)(_T1, _T2))
: ptr_(new func<R, T1, T2>(ptr))
{
}

template<typename T>
function(const T& obj)
: ptr_(new functor<T, R, T1, T2>(obj))
{
}

~function()
{
delete ptr_;
}

virtual R operator()(T1 a, T2 b)
{
return ptr_->operator()(a, b);
}

private:
base<R, T1, T2>* ptr_;
};

template<typename R, typename T1, typename T2>
class function<R (T1, T2)>

template<typename R, typename Class, typename T>
class member<R, Class*, T> : public base<R, Class*, T>

    template<typename Class, typename _R, typename _T2>
function(_R (Class::*ptr)(_T2))
: ptr_(new member<R, T1, T2>(ptr))
{
}

template<typename _R, typename _T1, typename _T2>
function(_R (*ptr)(_T1, _T2))
: ptr_(new func<R, T1, T2>(ptr))
{
}

template<typename T>
function(const T& obj)
: ptr_(new functor<T, R, T1, T2>(obj))
{
}

int get(int a, int b)
{
std::cout << a+b << std::endl;
return 0;
}

class Point
{
public:
int get(int a)
{
std::cout << "Point::get called: a = "<< a << std::endl;
return a;
}
int doit(int a, int b)
{
std::cout << "Point::doit called: a = "<< a+b << std::endl;
return a+b;
}
};

int main(int argc, char const *argv[])
{
function<int (int, int)> foo(get);
foo(10.1, 10.3);

function<int (Point*, int)> bar(&Point::get);
Point point;
bar(&point, 30);

function<int (int, int)> obj(boost::bind(&Point::doit, &point, _1, _2));
obj(90, 100);
}

20
Point::get called: a = 30
Point::doit called: a = 190

## 参考文献

1. boost中文手册. Improved Function Object Adapters 改良的函数对象适配器

（完）