C++ 中 Lambda 表达式与函数指针的区别

2025年3月18日 | 阅读 5 分钟

在本文中,我们将讨论 C++ 中 lambda 表达式和函数指针之间的区别。在深入了解关键差异之前,让我们先详细了解每个术语。

什么是 Lambda 表达式?

Lambda 表达式 是内联匿名函数,也就是说它们没有名称。Lambda 表达式包含捕获子句、参数、关键字、体、异常等不同组件。有三种捕获外部变量到我们的 Lambda 表达式 的方法。Lambda 表达式和函数对象(Functors)在实践中是相同的,只是其中一个被泛化了。Lambda 表达式是函数对象的紧凑类型。在与 STL 算法配合使用时,Lambda 表达式尤其有用。

语法

它具有以下语法:

Lambda 表达式由捕获子句、参数、返回类型和方法体组成。

捕获子句: 它是在 C++ 中要复制到 lambda 函数内部的变量列表。我们也可以使用它来声明和初始化变量。

参数: 可以使用一个或多个参数。

可选: 这是一个可选关键字,名为 mutable。当在 lambda 表达式中以按值传递的方式编写时,它允许更改被按值捕获的变量的值。

返回类型: 这是可选的,因为编译器会进行评估。但是,在某些更复杂的场景中,编译器无法确定返回类型,因此,这时我们就必须定义它。

方法体: 这与典型方法定义相同。当调用 lambda 表达式时,所有要执行的操作都将在此处概述。

C++ 中 Lambda 表达式的优势

C++ C++ 中 Lambda 表达式的几个优势如下:

  • 简洁的语法: Lambda 表达式也可以用来编写更少的代码,这些代码更容易阅读,因为无需声明单独的函数。
  • 匿名函数: 如果我们只需要使用一次或两次函数,它允许我们编写名称较少且没有不必要代码的函数。
  • 内联函数定义: Lambda 表达式可以即时创建,这通常会增强代码的清晰度并减少依赖性。
  • 捕获局部变量: Lambda 表达式仅限于表达式。但是,它们可以通过值或引用从周围作用域获取变量。
  • 更好的代码组织: 由于 Lambda 表达式是就地声明的,因此代码更整洁,并且辅助函数不会散布在整个文件中。

什么是函数指针?

指针 是地址的符号。它们允许程序模拟 引用传递 并创建和操作动态数据结构。由于迭代数组的元素,数组处理和其他复杂数据结构是使用指针的主要领域。

C++ 函数指针

  • 函数指针用于指向函数,就像指针用于指向变量一样。
  • 它用于存储函数的地址。
  • 函数指针可以被调用来执行这样的函数,或者作为参数传递给另一个函数。

函数指针的用途

  • 函数指针指向一个函数,而普通指针指向数据。通常,函数指针包含函数代码段的起始指令的地址。
  • 使用函数指针时,我们无需释放内存空间。
  • 通过使用函数名,我们也可以获得函数的地址。

C++ 中函数指针的优势

C++ 中函数指针的几个优势如下:

  • 动态函数选择: 函数指针允许在运行时选择正确的函数。因此,它们适用于回调、事件处理或决策制定等动态操作。
  • 回调机制: 函数指针用于使一个函数能够将其传递给另一个函数以启用回调。这可以用于事件驱动的编程,其中程序需要在事件发生时调用某些函数。
  • 代码重用灵活性: 在使用函数指针时,我们可以创建通用的计算函数或算法,这些函数或算法可以用于不同的函数而无需重写它们。这很重要,因为它将实现各种函数之间的代码可重用性和模块化。
  • 简化的事件处理: 函数指针用于低级语言,即嵌入式系统使用的语言,其中事件是环境的一部分。

Lambda 表达式和函数指针之间的主要区别

Difference between Lambdas and Function Pointers in C++

以下是 C++ 中 lambda 表达式和函数指针之间的一些主要区别:

特点Lambda 表达式函数指针
引言它于 C++11 引入,是 C++ 标准库的一部分。它是 C++ 的一部分,因为它的开发源于 C。
语法使用 [] 这样的 [](){} 定义特定内联函数的简单语法。在函数指针的上下文中,它遵循指针的标准语法,例如 void (*ptr)()。
类型推断编译器会自动通过推断确定 lambda 的数据类型。在定义函数指针时,必须指定用户类型。
上下文捕获它可以按值 [=] 或按引用 [&] 捕获外部作用域的变量。它无法访问外部块中的任何变量。它只能操作传递给函数的参数。
灵活性它允许捕获局部变量以及全局状态,并且更灵活。它的作用域定义较少,仅用于记录非上下文函数。
返回值自动返回值。当明确指定为函数指针类型时,不能使用它。
类型与 Lambda 中的函数对象相比,它们是未命名的,派生自函数类型以及特定且未命名的类型。很明显,函数指针是指向某种特定类型函数的指针。
性能它可以包含在内,并由编译器进行大量优化。由于函数指针调用会增加一个额外的间接层,因此它可能会稍慢一些。
开销如果需要捕获变量(取决于捕获模式),可能会产生一些额外开销。由于它们无法捕获任何内容,因此对局部变量没有开销。
可调用对象Lambda 表达式是可调用对象(或函数对象),它们也可以具有状态。函数指针仅表示只能传递没有状态或上下文的函数的指针。
与 STL 一起使用它经常与 STL 算法一起使用。也可以使用函数指针,尽管与使用函数对象相比,它不太方便且可读性较差。

结论

总而言之,Lambda 表达式函数指针 存在差异,但它们在 C++ 中都非常有用。Lambda 表达式效率最高,我们可以直接在代码中编写它们。它们可用于排序,使代码更简单易懂。另一方面,函数指针虽然可以更传统地编写,但广泛用于动态函数分派场景,如回调或事件处理程序,但它们没有上下文捕获和 Lambda 表达式的表达能力。在当前的 C++ 开发中,使用 Lambda 表达式更为常见,因为与函数指针相比,它们更通用且易于使用。