文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

释放 C++ 中 Lambda 表达式的强大威力

2024-11-30 16:24

关注

​Lambda 在 C++ 中提供了一种灵活而简洁的方式来编写类似函数的对象,并在现代 C++ 编程中被广泛使用。

Lambda 的定义使用以下语法:

[ capture list ] ( argument list ) -> return type { function body }

捕获列表(capture list)用于指定 lambda 中可访问的来自外部作用域的变量。变量可以通过值捕获、引用捕获或使用 this 捕获。

以下是在C++中使用 lambda 的几种不同方式。

1、函数回调

函数回调是将一个函数作为参数传递给另一个函数,并在接收函数稍后的时间调用该函数。您可以将 lambda 作为函数参数传递,其中它将在发生某个事件时执行。

示例:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};

// Lambda 表达式,用于查找两个数字的和
auto sum = [](int a, int b) { return a + b; };

int result = std::accumulate(numbers.begin(), numbers.end(), 0, sum);
std::cout << "Sum of elements in the vector: " << result << std::endl;

return 0;
}

在这个例子中,sum 变量是一个Lambda表达式,它接受两个参数 a 和 b,并返回它们的总和。std::accumulate 函数接受数字向量、结果的初始值和 sum 函数(Lambda 表达式)。该函数计算向量中所有元素的总和并返回结果,该结果被打印在屏幕上。

另一个例子:

#include <iostream>
#include <algorithm>
#include <vector>

int main()
{
std::vector<int> vec = { 1, 2, 3, 4, 5 };
int sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int x) { sum += x; });
std::cout << "The sum is: " << sum << std::endl;
return 0;
}

在这种情况下,lambda 表达式 [&sum](int x) { sum += x; } 被传递作为要应用于每个元素的函数。lambda 通过引用 & 捕获变量 sum,以便可以在 lambda 主体中进行修改。

两个例子都达到了相同的结果,但第二个例子使用了 std::for_each 算法和 lambda 表达式,这是在 C++ 中更现代、更简洁的技术。

2、默认捕获

当一个 lambda 表达式被声明时没有任何显式的捕获,其默认行为是通过引用捕获周围作用域中的变量。这被称为默认捕获。

例子:

#include <iostream>

int main() {
int x = 42;
auto f = [ ]() { std::cout << x << std::endl; };
f();
return 0;
}
#include <iostream>

int main()
{
auto square = [](int x) { return x * x; };
std::cout << "The square of 5 is: " << square(5) << std::endl;
return 0;
}

在第二个例子中,定义了一个 lambda 表达式并将其存储在名为 square 的变量中。这个 lambda 表达式接受一个 int 类型的参数 x,并返回 x * x 的值,即参数的平方。

在主函数中,这个 lambda 表达式被用作函数对象。通过传递一个值为 5 的参数来调用它,并使用 cout 流显示结果。

3、按值捕获

这是 lambda 表达式的最简单形式,其中你通过值传递变量给函数。当一个变量被按值捕获时,它的当前值被存储在闭包中,而当周围作用域中的变量发生改变时,它的值不会被更新。这可以通过将变量包含在方括号 [ ] 中来实现。

例子:

#include <iostream>

int main() {
int x = 42;
auto f = [x]() { std::cout << x << std::endl; };
f();
return 0;
}
#include <iostream>

int main() {
int x = 42;
auto f = [x](int y) { std::cout << x+y << std::endl;};
f(1);
return 0;
}

4、按引用捕获

你可以通过使用 & 符号将变量传递给 lambda 表达式来按引用捕获变量。当一个变量被按引用捕获时,它的当前值被存储在闭包中,并且在周围作用域中变量发生变化时被更新。这是通过在方括号[ ]中在变量前加上取地址运算符 & 来实现的。

例子:

#include <iostream>

int main() {
int x = 42;
auto f = [&x]() { std::cout << x << std::endl; };
f();
return 0;
}
#include <iostream>

int main() {
int x = 10;

auto add_one = [&x]() { ++x; };
add_one();
std::cout << x << "\n";

return 0;
}
#include <iostream>

int main() {
int x = 42;
auto f = [&x]() { std::cout << x << std::endl; };
f();
return 0;
}

5、可变Lambda表达式

默认情况下,由 lambda 表达式捕获的变量是常量,不能在 lambda 表达式体内修改。如果你想要在 lambda 表达式中修改捕获的变量,你可以将 lambda 表达式设为可变。可变lambda允许捕获的变量被修改。这是通过在方括号 [ ] 中包含可变关键字来实现的。

例子:

#include <iostream>

int main() {
int x = 42;
auto f = [x]() mutable { std::cout << ++x << std::endl; };
f();
return 0;
}

lambda 表达式类似于普通函数,但它们有一些关键的区别。例如,lambda 表达式的类型没有被显式指定,但可以由编译器推断出来。此外,lambda 表达式可以从周围的作用域中捕获变量,这使得它们非常适用于创建闭包和在 C++ 中使用函数式编程概念。

与传统函数相比,lambda 表达式具有一些性能优势:

总之,与传统函数相比,lambdas 可以通过减少开销、提高缓存位置、减少代码大小、提高灵活性和提高可读性来提高性能。

来源:Linux迷内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯