Boost源码剖析:C++泛型函数指针类

Boost源码剖析:C++泛型函数指针类,第1张

Boost源码剖析:C++泛型函数指针类,第2张

序幕

如你所知,Boost库是一个功能齐全、具有行业实力的库,众多C++权威的加入使其达到了巅峰。尤其是泛型的强大威力在其中发挥的淋漓尽致,令人瞠目结舌。

不过弱水三千,我们只拿一瓢饮料。下面,我试着从最简单的世界开始,一步一步带领你走进源代码的世界,探索boost::function(以下简称function)内部的微妙结构。

通常,在简单的情况下,对函数的调用简单而直观,就像这样:

int fun(int some val);

int main(){
fun(10);
}

但是,您可能需要在某个时候保存函数指针,并在以后的另一个时间调用它,如下所示:

int fun(int);
typedef int(* func _ handle)(int);

int main(){
func _ handle FH = fun;
...//做点什么
FH(10);
}

但是,如果乐趣的形式是void fun(int)呢?如你所见,乐趣可能有无数种形式。如果每种形式的乐趣都有一个对应的funC _ handle是typedef,程序员会不知所措,代码可能会变得臃肿难看。就算好玩是模仿功能?

幸运的是,C++泛型可以使代码变得优雅和精炼。面对无数的可能性,泛型是选择。因此,您只需要一个可以保存函数指针的通用模板类(对应于命令模式)。因为泛型编程有一个先天的优势——它可以在编译器的帮助下,根据用户提供的类型信息,在编译时被具体化(物化),所以一个泛型类可以有无限个实例化,也就是说,它可以容纳无限个可能类型的函数或类似函数的东西(如模仿函数)。这个类(Boost库中的类名是function)相对于函数指针应该有以下优点:

同一功能对象应能接受与其形式兼容的所有功能和模仿功能,如:

int f1(int);//这是一个函数,形式为int(int)
short F2(double);//这个函数的形式是short(double)

Struct functor //这是一个模仿函数类,形式为int(int)
{
int operator()(int){ }
};

函子F3;//创建一个模仿函数对象

boost::function < int(int)> func;// int(int)类型函数或仿函数
func = f1;//接受f1
func(10);//调用f1(10)
func = F2;//也可以接受短(双)型F2
func(10);//调用F2(10)
func = F3;//也可以接受仿函数F3
func(10);//调用f3(10)

该函数应该能够使用参数绑定和其他函数构造库。比如function也要能接受std::bind1st返回的模仿函数。这一点其实第一点就保证了。

当调用空的接受对象时,该函数应该具有可预测的行为。

显然,第一点是我们的重点。所谓形式上的兼容性,即对于:

R1 (T0,T1,T2,...,TN) = >函数类型1
R2 (P0,P1,P2,...,PN) = >函数类型2

两类功能(广义)只要:

1.R2可以含蓄地转化为R1。

2.所有Ti都可以隐式地转换成Pi (i取0,1,2,...)

也就是说boost:: function < function type 1 >可以接受FunctionType2的函数(注意反过来是不行的)。支持这个断言的理由是,只要Ti可以隐式转换为Pi,参数转发给实函数调用就是安全的,如果R2可以隐式转换为R1,返回实函数调用返回的值就是安全的。这里安全的意思是C++类型系统认为隐式转换不会丢失信息,或者会给出编译警告,但是可以编译。

后面会看到,boost::函数通过所谓的invoker非常巧妙地实现了这一点,并防止了形式不兼容的函数赋值。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Boost源码剖析:C++泛型函数指针类

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情