一、说明Boost.Lambda
在 C++11 之前,您需要使用像 Boost.Lambda 这样的库来利用 lambda 函数。从 C++11 开始,这个库可以被视为已弃用,因为 lambda 函数现在是编程语言的一部分。如果您在不支持 C++11 的开发环境中工作,您应该在转向 Boost.Lambda 之前考虑 Boost.Phoenix。 Boost.Phoenix 是一个较新的库,如果您需要在没有 C++11 的情况下使用 lambda 函数,它可能是更好的选择。
lambda 函数的目的是使代码更紧凑且更易于理解(请参见示例 43.1)。
示例 43.1。带有 lambda 函数的 std::for_each()的
#include <boost/lambda/lambda.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(),
std::cout << boost::lambda::_1 << "\n");
}
Boost.Lambda 提供了几个助手来创建无名函数。代码写在应该执行的地方,不需要包装在函数中,也不必显式调用函数。在示例 43.1 中,std::cout << boost::lambda::_1 << "\n" 是一个 lambda 函数,它需要一个参数,它在写入标准输出后跟一个新行。
boost::lambda::_1 是一个占位符,它创建一个需要一个参数的 lambda 函数。占位符中的数字决定了预期参数的数量,因此 boost::lambda::_2 预期两个参数,而 boost::lambda::_3 预期三个参数。 Boost.Lambda 只提供了这三个占位符。示例 43.1 中的 lambda 函数使用 boost::lambda::_1,因为 std::for_each() 需要一个一元函数。
包括 boost/lambda/lambda.hpp 以使用占位符。
请注意,\n 而不是 std::endl,在示例 43.1 中用于输出新行。如果您使用 std::endl,该示例将无法编译,因为 lambda 函数 std::cout << boost::lambda::_1 的类型与一元函数模板 std::endl() 预期的类型不同。因此,您不能使用 std::endl。
示例 43.2。带有 boost::lambda::if_then() 的 lambda 函数
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/if.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(),
boost::lambda::if_then(boost::lambda::_1 > 1,
std::cout << boost::lambda::_1 << "\n"));
}
头文件 boost/lambda/if.hpp 定义了可用于在 lambda 函数中创建 if 控制结构的结构。最简单的构造是函数模板 boost::lambda::if_then(),它需要两个参数:第一个参数是一个条件。如果条件为真,则执行第二个参数。两个参数都可以是 lambda 函数,如示例 43.2 所示。
除了 boost::lambda::if_then() 之外,Boost.Lambda 还提供函数模板 boost::lambda::if_then_else() 和 boost::lambda::if_then_else_return(),它们都需要三个参数。还为循环和转换运算符提供函数模板,并在 lambda 函数中抛出异常。 Boost.Lambda 定义的许多函数模板使得定义 lambda 函数成为可能,这些函数丝毫不逊色于普通的 C++ 函数。