(三)boost::lambda源码分析

 本文是lambda分析篇最重要的一篇。lambda源码比较庞大(把宏全部展开),只是对其中的小部分进行分析,小部分足以展示其难度和运行机理。

boost源码给我的感觉对基础知识要求很高,是对知识正确的运用(我们的朋友们已经走向了另一条路,喜马拉雅上还是要从中国这方爬比较合适)。lambda源码对模板技术的运用很高,比其它代码如pool,shared_ptr等等都要厉害。总体来看mpl源码是元编程的皎皎者,但是很难运用在实际的工作中。lambda应该是实际运用的出色者。

先看下面的代码:

首先,主要研究lambda的运用:

打印出容器中的元素,这些元素显然是连续的。如果要分开,可以写成:

简单的增加了后面的' '或是std::endl将使模板参数变得异常的复杂。

因此,先考虑不那么复杂的语句:

std::cout<<_1

上面语句一定先要展开_1,这个在源码中被定义成这样的形式:

上面要获得lambda_fuctor这个模板,它是由宏扩展而成:

上面这个流程先讨论到这儿。实际上由于这个流程指向的方向是非常复杂,只有充满勇气人才能人继续走下去。

前面讨论到:

std::cout<<_1

由于这个for_each:

所以实际上std::cout<<_1应该是这样的形式:

根据重载操作符的<<的规则,第一个参数必是std::cout,那么这个

函看起来是这个样子:

上面的operator<<从何而来?

由此语句展开:

展开过后为:

这个函数同相对应:

也就是:

A --------------------> std::basic_ostream<char,std::char_traits<char> >

boost::lambda::lambda_functor<boost::lambda::placeholder<1> > ------> const lambda_functor<Arg>&

而返回类型是:

为什么返回类型如此重要,因为如果后面还有输出内容,那么不能少。std::cout<<_1<<'  ',输出

' '少不了返回类型。

convert_ostream_to_ref_others_to_c_plain_by_default这个元函数类不讨论了。它的主要内容在

(一)boost::lambda分析中已经讨论了。

这样最终构造一个lambda_functor对象。

然后在for_each中,调用

lambda_functor调用如下:

上面的operator()中的call调用实际上:

 

std::cout<<_1与std::cout<<_1<<' '差别在哪儿?在于传入的args这个模板参数不同。

std::cout<<_1的模板参数类型是:

  

而std::cout<<_1<<' '的类型是:

可见要复杂得多。里面的boost::tuples::null_type可以略去不看。

如果仔细的阅读,还是可以理解的。不理解是不行的,只有理解了才能懂得其道理。

通过模板的递归调用最终还是std::cout<<_1<<' '这种形式。

这只是冰山一角,已足以展示其复杂性。

猜你喜欢

转载自blog.csdn.net/yshuise/article/details/5919585