跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ lambda 表达式
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++ Lambda表达式 = '''Lambda表达式'''是C++11引入的一项强大特性,它允许在代码中定义匿名函数对象(也称为闭包)。Lambda表达式常用于简化代码、实现回调函数或在需要临时函数的场景中使用。 == 基本语法 == Lambda表达式的基本语法如下: <syntaxhighlight lang="cpp"> [捕获列表](参数列表) -> 返回类型 { 函数体 } </syntaxhighlight> 其中: * '''捕获列表''':指定lambda表达式可以访问的外部变量 * '''参数列表''':与普通函数的参数列表类似 * '''返回类型''':可选的,如果省略则由编译器自动推导 * '''函数体''':包含要执行的代码 === 最简单的Lambda示例 === <syntaxhighlight lang="cpp"> #include <iostream> int main() { auto greet = []() { std::cout << "Hello, World!"; }; greet(); // 调用lambda return 0; } </syntaxhighlight> '''输出:''' <pre> Hello, World! </pre> == 捕获列表详解 == Lambda表达式可以通过捕获列表访问外部变量,有以下几种捕获方式: {| class="wikitable" |+ 捕获方式比较 |- ! 捕获方式 !! 语法 !! 描述 |- | 值捕获 || <code>[x]</code> || 创建x的副本 |- | 引用捕获 || <code>[&x]</code> || 引用外部变量x |- | 隐式值捕获 || <code>[=]</code> || 以值方式捕获所有外部变量 |- | 隐式引用捕获 || <code>[&]</code> || 以引用方式捕获所有外部变量 |- | 混合捕获 || <code>[=, &x]</code> || 大部分变量值捕获,x引用捕获 |} === 捕获示例 === <syntaxhighlight lang="cpp"> #include <iostream> int main() { int x = 10, y = 20; // 值捕获x,引用捕获y auto lambda = [x, &y]() { std::cout << "x: " << x << ", y: " << y << "\n"; y++; // 可以修改y,因为它是引用捕获 }; lambda(); std::cout << "After lambda, y is now: " << y << "\n"; return 0; } </syntaxhighlight> '''输出:''' <pre> x: 10, y: 20 After lambda, y is now: 21 </pre> == 参数和返回类型 == Lambda表达式可以像普通函数一样接受参数和指定返回类型。 === 带参数的Lambda === <syntaxhighlight lang="cpp"> #include <iostream> int main() { auto add = [](int a, int b) { return a + b; }; std::cout << "5 + 3 = " << add(5, 3) << "\n"; return 0; } </syntaxhighlight> '''输出:''' <pre> 5 + 3 = 8 </pre> === 指定返回类型 === 当函数体包含多个返回语句且类型不同,或者返回类型不明显时,需要显式指定返回类型。 <syntaxhighlight lang="cpp"> #include <iostream> int main() { auto divide = [](double a, double b) -> double { if(b == 0) return 0; // 返回double而非int return a / b; }; std::cout << "10 / 3 = " << divide(10, 3) << "\n"; std::cout << "10 / 0 = " << divide(10, 0) << "\n"; return 0; } </syntaxhighlight> '''输出:''' <pre> 10 / 3 = 3.33333 10 / 0 = 0 </pre> == 通用Lambda (C++14) == C++14引入了通用Lambda,可以使用<code>auto</code>作为参数类型。 <syntaxhighlight lang="cpp"> #include <iostream> int main() { auto print = [](auto value) { std::cout << value << "\n"; }; print(42); // int print(3.14); // double print("Hello"); // const char* return 0; } </syntaxhighlight> '''输出:''' <pre> 42 3.14 Hello </pre> == 初始化捕获 (C++14) == C++14允许在捕获列表中初始化变量,这在使用移动语义时特别有用。 <syntaxhighlight lang="cpp"> #include <iostream> #include <string> #include <utility> int main() { std::string str = "Hello"; // 移动捕获str auto lambda = [s = std::move(str)]() { std::cout << s << "\n"; }; lambda(); std::cout << "str is now: " << str << "\n"; // str已被移动 return 0; } </syntaxhighlight> '''输出:''' <pre> Hello str is now: </pre> == 可变Lambda == 默认情况下,值捕获的变量在lambda内是const的。使用<code>mutable</code>关键字可以修改这些副本。 <syntaxhighlight lang="cpp"> #include <iostream> int main() { int x = 0; auto counter = [x]() mutable { x++; // 修改副本 return x; }; std::cout << counter() << "\n"; // 1 std::cout << counter() << "\n"; // 2 std::cout << "Original x: " << x << "\n"; // 仍然是0 return 0; } </syntaxhighlight> '''输出:''' <pre> 1 2 Original x: 0 </pre> == 实际应用案例 == === STL算法中的Lambda === Lambda表达式常用于STL算法中作为谓词。 <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> numbers = {5, 2, 8, 1, 9, 3}; // 使用lambda排序 std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; // 降序排序 }); for(int n : numbers) { std::cout << n << " "; } return 0; } </syntaxhighlight> '''输出:''' <pre> 9 8 5 3 2 1 </pre> === 异步编程中的回调 === Lambda非常适合作为异步操作的回调函数。 <syntaxhighlight lang="cpp"> #include <iostream> #include <thread> #include <chrono> int main() { std::cout << "Starting async operation...\n"; std::thread worker([]() { std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "Async operation completed!\n"; }); std::cout << "Main thread continues...\n"; worker.join(); return 0; } </syntaxhighlight> '''输出:''' <pre> Starting async operation... Main thread continues... Async operation completed! </pre> == Lambda与函数指针 == Lambda表达式可以转换为函数指针,前提是它不捕获任何变量。 <syntaxhighlight lang="cpp"> #include <iostream> void call_func(void (*func)(const char*)) { func("Hello from function pointer"); } int main() { // 无捕获的lambda可以转换为函数指针 auto lambda = [](const char* msg) { std::cout << msg << "\n"; }; call_func(lambda); return 0; } </syntaxhighlight> '''输出:''' <pre> Hello from function pointer </pre> == Lambda表达式的类型 == 每个Lambda表达式都有唯一的、未命名的类型。可以使用<code>auto</code>或<code>std::function</code>来存储Lambda。 === 使用std::function === <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> int main() { std::function<int(int, int)> add = [](int a, int b) { return a + b; }; std::cout << "Sum: " << add(5, 3) << "\n"; return 0; } </syntaxhighlight> '''输出:''' <pre> Sum: 8 </pre> == 性能考虑 == Lambda表达式通常会被编译器内联,因此性能与普通函数相当。但是: * 捕获大量变量会增加Lambda对象的大小 * 使用<code>std::function</code>会有轻微的性能开销 * 简单的无捕获Lambda可以像函数指针一样高效 == 总结 == Lambda表达式是C++中强大的功能,它: * 允许在需要的地方定义匿名函数 * 可以捕获上下文中的变量 * 语法简洁,适合与STL算法配合使用 * 在C++14和C++17中得到了进一步扩展 掌握Lambda表达式可以显著提高代码的可读性和表达力,特别是在函数式编程风格和异步编程中。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 函数]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)