lambda 表达式是匿名的内联函数对象,捕获外部变量,允许在函数指针之外访问和修改外部变量的状态;闭包包含 lambda 表达式和捕获的变量,保留对外部变量状态的引用;函数指针指向函数的地址,无法访问外部变量。
C++ lambda 表达式与闭包与函数指针的对比
简介
在 C++ 中,lambda 表达式、闭包和函数指针是处理函数指针的强大工具。尽管它们之间存在相似之处,但它们在功能、语法和用途方面也有显着的差异。本文将深入探讨这些概念之间的对比,提供代码示例以阐明它们的特性。
立即学习“C++免费学习笔记(深入)”;
lambda 表达式
lambda 表达式是匿名的内联函数对象。它使用 [capture_list](https://en.cppreference.com/w/cpp/language/lambda_expressions#Capture_list) 捕获外部变量,并用 [parameters](https://en.cppreference.com/w/cpp/language/lambda_expressions#Syntax) 指定函数参数和主体。
auto increment = [](int x) { return x + 1; };
闭包
闭包是由 lambda 表达式或函数对象与它捕获的变量一起形成的实体。由于闭包包含它所访问的外部变量的副本,因此它可以保留对这些变量的状态的引用,即使外部函数已经退出也是如此。
函数指针
函数指针指向函数的内存地址。它允许将函数传递给其他函数或存储在数据结构中。函数指针的语法如下:
int (*add)(int, int);
对比
特性 | lambda 表达式 | 闭包 | 函数指针 |
---|---|---|---|
创建 | 匿名的内联函数对象 | 封装了 lambda 表达式和捕获变量 | 指向函数的地址 |
捕获变量 | 可以使用 capture_list 捕获 | 是,通过 lambda 表达式捕获 | 不支持捕获变量 |
状态 | 可以保持对外部变量状态的引用 | 可以保持对外部变量状态的引用 | 无法访问外部变量 |
语法 | 使用 [ ] 语法 | 包含 lambda 表达式和外部变量 | 使用类型和星号(*) |
实战案例
使用 lambda 表达式排序容器
std::vector<int> v = {5, 2, 8, 1}; std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
使用闭包存储状态
auto counter = []() { int count = 0; return [&count] { return ++count; }; }; auto c1 = counter(); auto c2 = counter(); std::cout << c1() << std::endl; // 1 std::cout << c2() << std::endl; // 1
使用函数指针传递函数
void print(int (*func)(int)) { std::cout << func(10) << std::endl; } int add(int x) { return x + 1; } print(add); // 11
以上就是C++ lambda 表达式与闭包与函数指针的对比的详细内容,更多请关注本网内其它相关文章!