C++ Lambda 表达式: 简洁与高效的完美结合
文章目录
- 1. 什么是 Lambda 表达式?
- 2. Lambda 表达式的实际用法
- 排序操作
- 配合标准算法库使用
- 自定义捕获
- 返回 Lambda 的高阶函数
- 3. Lambda 的高级特性
- `mutable` 修饰符
- 泛型 Lambda
- 4. 总结
在现代 C++ 开发中, Lambda 表达式以其匿名性和灵活性深受开发者喜爱. 从排序和筛选到高阶函数和泛型支持, Lambda 几乎适用于每一个需要函数对象的场景. 本文将详细介绍 Lambda 的核心概念, 并通过多个实用例子展现其强大功能.
1. 什么是 Lambda 表达式?
Lambda 表达式是 C++ 提供的一种匿名函数形式, 可以在代码中定义并直接使用. 它让代码更加紧凑, 无需额外定义函数, 从而提升开发效率.
基本语法如下:
[捕获列表](参数列表) -> 返回类型 {
// 函数体
};
- 捕获列表: 决定哪些外部变量可以在 Lambda 内部使用.
- 参数列表: Lambda 的输入参数.
- 返回类型: 如果不显式声明, 编译器会自动推断.
- 函数体: Lambda 实现的具体逻辑.
2. Lambda 表达式的实际用法
排序操作
在排序操作中, Lambda 可以直接作为 std::sort
的比较函数, 让代码更加简洁. 例如:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
struct Record {
std::string primary;
std::string secondary;
};
bool LessRecord(const Record& p1, const Record& p2) {
return p1.primary < p2.primary ||
(p1.primary == p2.primary && p1.secondary < p2.secondary);
}
int main() {
std::vector<Record> records = {{"A", "1"}, {"B", "0"}, {"a", "2"}};
// before
std::sort(records.begin(), records.end(), LessRecord);
// after
std::sort(records.begin(), records.end(),
[](const Record& p1, const Record& p2) {
return p1.primary < p2.primary ||
(p1.primary == p2.primary && p1.secondary < p2.secondary);
});
// also support ranges
std::ranges::sort(records, [](const Record& p1, const Record& p2) {
return p1.primary < p2.primary ||
(p1.primary == p2.primary && p1.secondary < p2.secondary);
});
for (const auto& record : records) {
std::cout << record.primary << " " << record.secondary << std::endl;
}
return 0;
}
输出:
A 1
B 0
a 2
配合标准算法库使用
除了sort
, 在标准算法库的中, 通过 Lambda 表达式可以省去额外定义工具函数, 就地解决:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
struct Record {
std::string primary;
std::string secondary;
};
int main() {
std::vector<Record> records = {{"A", "1"}, {"B", "0"}, {"a", "2"}};
// also support ranges
std::ranges::sort(records, [](const Record& p1, const Record& p2) {
auto toLower = [](char c) { return std::tolower(c); };
return std::ranges::lexicographical_compare(p1.primary, p2.primary,
std::less{}, toLower, toLower);
});
for (const auto& record : records) {
std::cout << record.primary << " " << record.secondary << std::endl;
}
return 0;
}
输出:
A 1
a 2
B 0
自定义捕获
通过捕获外部变量, Lambda 的灵活性得以提升. 例如, 累加数组元素时使用引用捕获:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec{1, 2, 3, 4, 5, 6};
double sum = 0.0;
std::for_each(vec.begin(), vec.end(), [&sum](double d) { sum += d; });
std::cout << "Total: " << sum << '\n';
return 0;
}
输出:
Total: 21
返回 Lambda 的高阶函数
Lambda 还能作为返回值生成动态函数, 例如:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
auto make_interest_func = [](double rate) {
return [rate](double principal) { return principal * (1 + rate); };
};
// 创建一个计算 5% 利息的函数
auto calculate_interest = make_interest_func(0.05);
std::cout << "Amount with interest: " << calculate_interest(100) << '\n';
return 0;
}
输出:
Amount with interest: 105
3. Lambda 的高级特性
mutable
修饰符
如果需要修改按值捕获的变量, 可以使用 mutable
关键字:
#include <iostream>
#include <utility>
using namespace std;
int main() {
auto fib = [i = 0, j = 1]() mutable {
i = std::exchange(j, i + j);
return i;
};
for (int i = 0; i < 10; i++) {
cout << fib() << ", ";
}
return 0;
}
输出
1, 1, 2, 3, 5, 8, 13, 21, 34, 55,
泛型 Lambda
通过 auto
参数, Lambda 可支持多种类型:
#include <iostream>
#include <string>
using namespace std::string_literals;
int main() {
auto add = [](auto x, auto y) { return x + y; };
std::cout << add(1, 2) << '\n'; // 输出 3
std::cout << add(1.5, 2.5) << '\n'; // 输出 4.0
std::cout << add(std::string("Hello "), "world.") << '\n'; // 输出 HelloWorld
return 0;
}
输出:
3
4
Hello world.
4. 总结
C++ Lambda 表达式为开发者提供了强大的工具, 从提升代码简洁性到支持高级特性, 极大地优化了开发效率. 无论是简单的排序还是复杂的高阶函数, Lambda 都展现了其灵活性和强大能力. 在实际项目中, 合理利用 Lambda 表达式, 能够显著提升代码质量和开发效率.
希望本文能够帮助你深入理解和掌握 C++ Lambda 表达式的用法. 如果你有任何疑问或想法, 欢迎留言讨论!