C++的lambda表达式

2025-06-15更新于 2025-11-19663 字5 分钟C++
目录

lambda的表达方法及其区别

1.lambde的方法一 []()

1.注意事项

  • 这个方法的作用域只限于它自己,不能使用外部变量
  • 如果尝试在 [] 的 Lambda 中使用外部变量,会产生编译错误

2.特点

Lambda 不能访问任何外部的变量,只能操作传递给它的参数或者使用 Lambda 内部声明的变量。

3.用法

当你不需要在 Lambda 中使用外部作用域的变量时,可以用空捕获列表 []

1.当你不需要捕获变量时

cpp
void someFunction() {
    int x = 10;
    auto lambda = []() {
        // 不捕获任何变量,无法访问 x
        std::cout << "This will not access x" << std::endl;
    };
    lambda();
}

2.当你想要捕获一个以及多个变量时

cpp
// 这是捕获一个值的方法
void someFunction() {
    int x = 10;
    auto lambda = [x]() {  // 通过值捕获 x
        std::cout << x << std::endl;
    };
    lambda();
}

2.方法2 [&]()

1.主要事项

  • 需要确保 Lambda 的生命周期不会超出捕获的外部变量的生命周期,否则就会导致未定义行为(Dangling Reference)。
  • [&] 捕获的是所有外部变量引用,如果只想捕获特定变量,最好手动列出。

2.特点

  • 捕获所有外部变量的引用,允许 Lambda 内对它们进行修改。
  • 修改外部变量会直接影响原始变量。

3.用法

用 [&] 捕获外部作用域的所有变量通过引用,这意味着你可以在 Lambda 中修改外部变量,它们的值会在 Lambda 外部同步更新。

cpp
		void someFunction() {
		    int x = 10;
		    auto lambda = [&]() {
		        // 通过引用捕获 x,可以修改外部的 x
		        x = 20;
		        std::cout << x << std::endl;  // 输出 20
		    };
		    lambda();
		    std::cout << x << std::endl;  // 外部的 x 也变成了 20
		}

3.方法三 [*]()

1.注意事项

  • 如果 Lambda 内需要修改外部变量并同步到外部,[*] 是不适合的,你需要改用 [&] 或手动捕获引用。
  • 在捕获大对象时,捕获整个作用域的值可能会有性能开销。

2.特点

  • 捕获所有外部变量的值,即 Lambda 内的变量是独立的拷贝,修改不会影响外部变量。
  • Lambda 使用的是外部变量的快照,执行时外部变量的变化不会反映到 Lambda 内部。

3.用法

cpp
		void someFunction() {
		    int x = 10;
		    auto lambda = [*]() {
		        // 捕获外部变量 x 的值,但无法修改外部的 x
		        std::cout << x << std::endl;  // 输出 10
		    };
		    lambda();
		
		    x = 30;
		    lambda();  // 再次调用,仍然输出 10,因为它捕获的是初始的 x 值
		}

2.其他注意事项

  • 生命周期问题:在使用 [&] 捕获外部变量时,一定要确保 Lambda 的生命周期不会超过外部变量的生命周期,否则会导致引用悬挂的错误。
  • 捕获特定变量:可以只捕获部分外部变量,而不是全部。例如 [x, &y] 表示通过值捕获 x,通过引用捕获 y。
  • 捕获 this 指针:如果你在类的成员函数中使用 Lambda,可以用 [this] 捕获当前对象的指针,方便访问成员变量和成员函数。
cpp
	class MyClass {
	public:
		int value = 100;
	
		void myMethod() {
			auto lambda = [this]() {
				std::cout << value << std::endl;  // 通过 this 捕获成员变量
			};
			lambda();
		}
	};

3.总结

  • **[]**:不捕获外部变量,完全独立。
  • **[&]**:捕获所有外部变量的引用,可以修改外部变量。
  • **[*]**:捕获所有外部变量的值,修改 Lambda 内部变量不会影响外部变量。

希望我的博客能够对你有帮助

hhhh6448

hhhh6448

转载请注明出处,欢迎留言交流~

评论

评论区还没开放,部署评论服务后就能留言啦~

主题色