C++ Boost Lambda表达式详解
无水先生 人气:0lambda表达式格式
lambda表达式的格式
[捕捉列表](参数列表)mutable->返回值类型{ 语句部分 };
其中参数列表、返回值类型是可选的,捕捉列表、函数体可以为空。
先来看一个较为简单的lamda表达式
int main(void) { auto add = [](int a, int b)->int {return a + b; }; cout << add(1, 2) << endl; return 0; }
mutable可以省略,暂时不考虑。
- 捕捉列表,捕捉列表的
[]
是千万不能省略的,编译器会根据[]
判断该表达式是否为lambda表达式,捕捉列表能够捕捉上下文的变量提供给lambda表达式使用。 - 参数列表,就和普通的函数传参是一样的,如果不需要参数,那么可以连同
()
一起省略 - mutable:默认情况下,lambda表达式参数列表和捕捉列表被修饰成const属性,而mutable的作用就是取消它的const属性。如果使用了mutable参数一定不能省略,如果参数为空,那么需要保留
()
。 - ->返回值类型。返回值类型明确或没有返回值的情况下,该部分可省略,编译器会对返回值类型进行推导。
- 语句部分。和不同函数的函数体内语句部分是一样的含义,函数体内不仅可以使用它的参数,还可以使用所有捕获到的变量。
所以最简单的lambda表达式应该是[]{}
lambda表达式又被称为匿名函数,无法被直接调用,它的底层其实也是仿函数类。需要借助auto将表达式赋值给一个变量。
说明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 <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 提供了几个助手来创建无名函数。代码写在应该执行的地方,不需要包装在函数中,也不必显式调用函数。在示例 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++ 函数。
加载全部内容