写给我自己看的
在接触c++function前,我先接触了C#的委托,
class Test
{
delegate int delegate_test(int a,int b);
delegate_test TestDelegate;
public void Run()
{
TestDelegate=this.Add;
TestDelegate(1, 2);
}
int Add(int a,int b)
{
return a+b;
}
}
使用起来很是方便,当时想到C++也可以实现一个类似的,因为template可以完成,当时完成的版本大致如下:
#include <assert.h>
//基类定义接口Invoke,由子类实现
template<typename Return, typename Para>
class Function1Base
{
public:
virtual Return Invoke(Para para) = 0;
};
// 对函数指针包装
template<typename Return, typename Para>
class Function1Fun :public Function1Base<Return, Para>
{
public:
typedef Return(*FunType)(Para);
Function1Fun(FunType fun)
{
_fun = fun;
}
private:
virtual Return Invoke(Para para)
{
return (*_fun)(para);
}
FunType _fun;
};
// 对成员函数指针包装
template<typename Type, typename Return, typename Para>
class Function1MemFun :public Function1Base<Return, Para>
{
public:
typedef Return(Type::*FunType)(Para);
Function1MemFun(FunType fun, Type* pType)
{
_fun = fun;
_pType = pType;
}
private:
virtual Return Invoke(Para para)
{
return (_pType->*_fun)(para);
}
FunType _fun;
Type* _pType;
};
// 一个参数的特化版本
template<typename Return, typename Para>
class function1
{
public:
typedef Function1Base<Return, Para> BaseType;
function1(BaseType* pBase)
{
_pBase = pBase;
}
~function1()
{
if (_pBase) {
delete _pBase;
_pBase = NULL;
}
}
Return operator()(Para para)
{
return _pBase->Invoke(para);//调用
}
private:
function1(const function1&);
function1 operator=(const function1&);
BaseType* _pBase;
};
template<typename Type,typename Return, typename Para>
inline Function1Base<Return, Para>* bind(Return(Type::*fun)(Para), Type* pType)
{
return new Function1MemFun<Type,Return,Para>(fun, pType);
}
template<typename Return, typename Para>
inline Function1Base<Return, Para>* bind(Return(*fun)(Para))
{
return new Function1Fun<Return, Para>(fun);
}
class Test
{
public:
int mem_fun(int a)
{
return a;
}
static int static_fun(int a)
{
return a;
}
};
int main()
{
Test f_Test;
function1<int,int> f_fun1=bind(&Test::mem_fun, &f_Test);
function1<int,int> f_fun2=bind(&Test::static_fun);
assert(1 == f_fun1(1));
assert(2 == f_fun2(2));
return 0;
}
后来接触到function,function的接口定义让我无比膜拜,我自己实现的版本要实现拷贝,需要定义clone函数,而且内存的频繁分配,接口也不友好。而function常见使用如下:
#include <functional>
#include <assert.h>
using namespace std;
class Test
{
public:
int mem_fun(int a)
{
return a;
}
static int static_fun(int a)
{
return a;
}
int operator()(int a)
{
return a;
}
};
int main()
{
Test f_Test;
function<int(int)> f_fun1=bind(&Test::mem_fun, &f_Test,placeholders::_1);
function<int(int)> f_fun2=&Test::static_fun;
function<int(int)> f_fun3 =f_Test;
assert(1 == f_fun1(1));
assert(2 == f_fun2(2));
assert(3 == f_fun3(2));
return 0;
}
function可以是函数指针,成员函数指针,仿函数。看到int(int)时,我真是石化,这是什么玩意?,placehoders就不用说了,一直想不明白_1是什么玩意?这时候接触到刘未鹏的源码分析,感觉不明觉厉,后来modern c++ design,脑洞大开,到此,我的c++ template之门打开,但是也基本到那本书结束,不能否认元编程的快乐,但是我认为一个程序的可维护性也很重要,元编程对库作者而言是利器,但是实际项目中还是oo的天下。后来是C++11,将function收入标准库,我完全对function依赖。最近要写一个库,当库的使用者不想使用boost时,而编译器也不支持c++11或tr1时,我自已重复造轮子,把functinon实现了一遍(当然只实现了我认为对项目有用的接口),又学习到很多东西,决定写一个function的源码分析。
向刘未鹏致敬,从他博客学习颇多。