摘要:C++标准库里提供了多种算法,这些算法可以简化我们工作,可是这些算法都会需要一个函数对象作为其参数,有时又会不方便。本文讲述最重要也是最基础的算法std::for_each算法,它遍历一个序列,并执行一个操作,同时本文也讲述如何使得创建函数对象更方便快捷。
我们先来看看std::for_each最简单和直接的用法,接着关注一下std::for_each更多创造性的用法。这个简单而直接的例子首先定义一个函数对象类型,然后调用std::for_each对一个迭代器组进行遍历操作。
看了这个代码大家自然地产生了一个疑问,就是只是把向量里10元素设置一下值,为什么为直接使用一个for循环,而要如此费力地使用for_each,并且还要自己定义一个新的类型,这多难受。不错,就上面的例子使用for循环明显有优势,代码里也要显著减少。所以依常规方式使用for_each很多时候并不一定有更优秀的代码,这也是for_each等STL算法一直都难以被大量应用的一个原因:尽管功能强大,但使用不方便。有许多尝试和努力来解决这一不方便,从而STL算法真正成为方便可用的工具。
使用不方便在STL设计之初就已经被认识,所以STL专门提供了一些简化使用设施,这就是预定义的函数对象和函数适配器。这些函数对象和函数适配器对简化算法调用直到一定的作用,关于它的更多内容请参看这里。
下面给出一个使用STL函数对象与适配器一个示例,由于这些设施功能仍然简陋,所以不能轻易实现上例的功能,此处的示例是把10个元素都同时加1:
boost对STL进行了很大扩展,并且这种扩展仍然在进行着。在上面的例子中我们看到一个std::bind1st函数,现在boost库对其进行的扩展,使得boost::bind可以做更多的事,同时语法也更统一。boost::lambda 则走得更远,它实际上是使用库的形式实际著名的lambda表达式,也就是“就地”小函数,它让我们定义一个简单而直观的函数变得异常容易,如此诸如std::for_each的算法需要的函数对象也就是更容易做到了。下面使用boost库来实现最初那个示例,你将看到它是如此得简单:
看到如此精致代码是否已心动,更多内容可以参数boost::lambda库文档(中文)。
lambda表达式实际上是函数式语言的核心,理论上说它现在现有的各种语言都可以构成等价。大家可能知道冯诺依曼机,在历史上lambda与冯诺依曼机是等价的。是现代计算机理论的3个源头之一。它如此重要,所以在下一代C++标准里已经把它加入核心语言,如此我们就不再需要boost::lambda库了。下面示例C++0x中最初示例的样子,它在GCC 4.5.1中编译并运行正确。
现在可以看出来就简单的方法原来在C++0x中,期待中……
联系客服