在C++中,Lambda表达式是一种用来创建匿名函数的机制,它可以在需要函数作为参数的地方方便地定义并使用函数。Lambda表达式的语法形式如下:
[capture list] (parameters) -> return_type { body }
-
capture list(捕获列表):用来捕获外部变量,可以是值传递或引用传递。捕获列表可以为空,也可以使用=表示按值捕获所有外部变量,或使用&表示按引用捕获所有外部变量,还可以通过列表指定具体的变量进行捕获。
-
parameters(参数列表):与普通函数的参数列表类似,指定了Lambda函数的形参。
-
return_type(返回类型):指定了Lambda函数的返回类型,可以省略(根据返回值类型的推导)。
-
body(函数体):Lambda函数的具体实现。
在Lambda表达式中,捕获列表用于指定在函数体中可以访问的外部变量,并控制了这些变量的访问方式。C++中常见的捕获列表包括:
1.按值捕获(capture by value):通过值的方式捕获外部变量,Lambda函数内部使用的是外部变量的副本。可以使用=来表示按值捕获所有外部变量,也可以使用变量名列表指定具体的变量按值捕获。
#include <iostream>
int main()
{
int x = 5;
int y = 10;
// 捕获x和y的副本
auto lambda = [=]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
x = 100;
y = 200;
lambda(); // 输出:x = 5, y = 10,因为Lambda函数捕获的是x和y的初始值
std::cout << "x = " << x << ", y = " << y << std::endl; // x = 100, y = 200
return 0;
}
2.按引用捕获(capture by reference):通过引用的方式捕获外部变量,Lambda函数内部使用的是外部变量的引用。可以使用&来表示按引用捕获所有外部变量,也可以使用变量名列表指定具体的变量按引用捕获。
#include <iostream>
int main()
{
int x = 5;
int y = 10;
// 捕获x和y的引用
auto lambda = [&]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
x = 100;
y = 200;
lambda(); // 输出:x = 100, y = 200,因为Lambda函数捕获的是x和y的引用
return 0;
}
当捕获列表为空时,Lambda表达式不捕获任何外部变量,即在Lambda函数体内部无法访问任何外部变量。这种情况下,Lambda函数只能使用函数参数或者全局变量等在其作用域内可见的变量。
下面是一个示例:
#include <iostream>
int main() {
int x = 5;
int y = 10;
// 捕获列表为空,Lambda函数无法访问任何外部变量
auto lambda = []() {
// x 和 y 在这里不可见
std::cout << "Hello, Lambda!" << std::endl;
};
lambda(); // 输出:Hello, Lambda!
return 0;
}
在这个示例中,Lambda函数内部无法访问外部变量 x 和 y,因为捕获列表为空。Lambda函数仅仅打印了一条简单的消息,没有涉及任何外部变量。
这种情况下,Lambda函数的作用类似于普通的函数,它们之间的区别在于Lambda函数具有捕获外部变量的能力,而普通函数则没有这种能力。
3.按值捕获指定变量,按引用捕获其他变量:可以混合使用值捕获和引用捕获来捕获不同的外部变量,以满足不同的需求。
#include <iostream>
int main() {
int x = 5;
int y = 10;
// 捕获x的副本,捕获y的引用
auto lambda = [x, &y]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
x = 100;
y = 200;
lambda(); // 输出:x = 5, y = 200,因为x被捕获为副本,y被捕获为引用
return 0;
}
4.按引用捕获指定变量,按值捕获其他变量:与上面相反,可以将某些变量按引用捕获,而将其他变量按值捕获。
#include <iostream>
int main() {
int x = 5;
int y = 10;
// 捕获x的引用,捕获y的副本
auto lambda = [&x, y]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
x = 100;
y = 200;
lambda(); // 输出:x = 100, y = 10,因为x被捕获为引用,y被捕获为副本
return 0;
}
这些示例展示了不同捕获方式的用法和效果,可以根据具体的需求选择适合的捕获方式来访问外部变量。