您的位置:首页 > 其它

Boost Lambda Library

2013-05-15 12:56 162 查看
In a nutshell
Boost Lambda Library(简称为 BLL )是一个C++ 模板库,为 C++ 实现了lambda abstractions 的形式。这个术语起源于函数式编程和lambda演算,一个lambda abstraction定义一个无名函数。BLL的主要动机是为定义供STL算法使用的无名函数对象提供灵活性和便利性。在讲解一个库是什么的时候,一行代码往往胜过千言万语,下面这一行输出以空格分隔的某个 STL 容器 a 中的元素:
for_each(a.begin(), a.end(), std::cout << _1 << ' ');

表达式 std::cout << _1 << ' ' 定义了一个一元的函数对象。变量 _1 是这个函数的形式参数,相当于一个实际参数的 placeholder(占位符) 。在 for_each 的每一次迭代中,针对实际参数 a 中的元素调用这个函数。这个实际参数取代了占位符,而这个函数体被求值。

BLL 的本质是让你就像上面那个一样,在紧挨着 STL 算法调用位置的上面,定义小的无名函数对象。

匿名函数 —— 又称为lambda函数 (lan bu(mu)da,兰布达),已经在多种编程语言中存在 ,但C++除外。不过在Boost.Lambda库的帮助下,现在C++应用中也可以使用它们了。
注意:lambda函数的目标是令源代码更为紧凑,从而也更容易理解。

例如:
#include <iostream> 
#include <vector> 
#include <algorithm> 
void print(int i) 
{ 
    std::cout << i << std::endl; 
} 
int main() 
{ 
    std::vector<int> v; 
    v.push_back(1); 
    v.push_back(3); 
    v.push_back(2); 
    std::for_each(v.begin(), v.end(), print); 
}
这段程序接受容器v中的元素并使用print()函数将它们写出到标准输出流。由于print()只是输出了一个简单的int,所以该函数的实现相当简单。严格来说,它是如此地简单,以致于如果可以在std::foreach()算法里面直接定义它的话,会更为方便。从而省去增加一个函数的需要。另外一个好处是代码更为紧凑,使得算法与负责数据输出的函数不是局部性分离的。Boost.Lambda正好使之成为现实。
#include <boost/lambda/lambda.hpp> 
#include <iostream> 
#include <vector> 
#include <algorithm> 
int main() 
{ 
    std::vector<int> v; 
    v.push_back(1); 
    v.push_back(3); 
    v.push_back(2); 
    std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << "\n");// 使用std::endl编译不过 
}
Boost.Lambda提供了几个结构来定义匿名函数。代码就被置于执行的地方,从而省去将它包装为一个函数再进行相应的函数调用的开销。
Boost.Lambda定义了三个占位符,名为_1,_2和_3 。这些占位符是定义在单独的名字空间 的。因此,第一个占位符是通过boost::lambda::_1来引用的。为了满足编译器的要求,必须包含相应的头文件boost/lambda/lambda.hpp。
虽然代码的位置位于std::foreach()的第三个参数处,看起来很怪异,但Boost.Lambda可以写出正常的C++代码。通过使用占位符,容器v的元素可以通过<<传给std::out以将它们输出到标准输出流。

注意 :虽然Boost.Lambda非常强大,但也有一些缺点 。要在以上例子中插入换行的话,必须用"/n"来代替std::endl才能成功编译 。因为,一元std::endl模版函数所要求的类型不同于lambda函数std::cout<<boost::lambda::_1的函数,所以在此不能使用它。

下一个版本的C++标准很可能会将lambda函数作为C++语言本身的组成部分加入,从而消除对单独的库的需要。但是在下一个版本到来并被不同的编译器厂商所采用可能还需要好几年。在此之前,Boost.Lambda被证明是一个完美的替代品。
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/if.hpp> 
#include <iostream> 
#include <vector> 
#include <algorithm> 
int main() 
{ 
    std::vector<int> v; 
    v.push_back(1); 
    v.push_back(3); 
    v.push_back(2); 
    std::for_each(v.begin(), v.end(), 
    boost::lambda::if_then(boost::lambda::_1 > 1, std::cout << boost::lambda::_1 << "\n")); 
}
这个例子只将大于1的元素输出到标准输出流。
头文件boost/lambda/if.hpp定义了几个结构,允许在lambda函数内部使用if语句。
最基本的结构是,boost::lambda::if_then()模板函数,它要求两个参数:第一个参数对条件求值,如果为真,则执行第二个参数。如例中所示,每个参数本身都可以是lambda函数。
除了boost::lambda::if_then(),Boost.Lambda还提供了boost::lambda::if_then_else()和boost::lambda::if_then_else_return()模板函数,它们都要求三个参数。另外还提供了用于实现循环、转型操作符,甚至是throw,允许lambda函数抛出异常的模板函数。

注意 :虽然可以用这些模板函数在C++中构造出复杂的lambda函数,但是必须要考虑其它方面,如可读性和可维护性。因此,lambda函数的好处通常随着它的复杂性而降低 。多数情况下,更为合理的方法是用熟悉的C++结构定义一个单独的函数。

参考:
Chapter 3: Function Objects
http://zh.highscore.de/cpp/boost/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: