C++11 中引入了 lambda 表达式,它是一个可以创建匿名函数的语法结构,可以方便地定义一些临时性的函数,这些函数可以在需要的时候被立即调用或者传递给其他函数。
Lambda 表达式的语法非常简单,它由一个中括号包围的参数列表、一个可选的mutable修饰符、一个可选的异常声明、一个可选的返回类型和一个由大括号包围的函数体组成。
下面举一个例子,说明 lambda 表达式的妙用和优雅:
假设我们有一个数组,我们想将其中的所有元素都乘以 2,并且只想保留其中的奇数。
(1)不使用 lambda 表达式的代码实现:
在不使用 lambda 表达式的例子中,我们定义了两个仿函数类 MultiplyByTwo 和 IsOdd,它们都实现了函数调用运算符 (),并且可以像普通函数一样被调用。
#include <iostream>
#include <vector>
#include <algorithm>
class MultiplyByTwo
{
public:
int operator()(int n) const
{
return n * 2;
}
};
class IsOdd
{
public:
bool operator()(int n) const
{
return n % 2 != 0;
}
};
int main()
{
std::vector<int> numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> result;
std::transform(numbers.begin(), numbers.end(),
std::back_inserter(result),
MultiplyByTwo()); // 乘以 2
result.erase(std::remove_if(result.begin(), result.end(),
IsOdd()), // 只保留奇数
result.end());
for (auto n : result)
{
std::cout << n << ' ';
}
std::cout << std::endl;
return 0;
}
(2)使用 lambda 表达式,可以轻松实现这个功能,而且代码看起来非常优雅:
在使用 lambda 表达式的例子中,我们直接定义了两个匿名函数,它们也是仿函数。实际上,lambda 表达式本质上就是一个匿名的函数对象,它可以像普通函数一样被调用。
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> result;
std::transform(numbers.begin(), numbers.end(),
std::back_inserter(result),
[](int n) { return n * 2; }); // 乘以 2
result.erase(std::remove_if(result.begin(), result.end(),
[](int n) { return n % 2 == 0; }), // 只保留奇数
result.end());
for (auto n : result)
{
std::cout << n << ' ';
}
std::cout << std::endl;
return 0;
}
结论:
使用 lambda 表达式可以避免定义额外的仿函数类,从而使代码更加简洁和易读。当然,在一些复杂的场景下,使用仿函数类可能更加合适,因为它们可以更好地封装复杂的业务逻辑。