C++11 引入了 Lambda 表达式,它是一种匿名函数对象,允许我们在需要的地方定义一个简短的函数,而无需显式地定义一个命名函数。Lambda 表达式的基本语法如下
[capture list] (parameter list) -> return type { function body }
cpature list:用于捕获外部变量,可指定 Lambda 表达式如何访问其所在作用域中的变量
parameter list: 和普通函数的参数列表类似
return type:可省略,编译器会自动推导返回类型
function body:Lambda函数具体的实现
值捕获会将外部变量的副本存储在 Lambda 表达式中。在 Lambda 表达式创建时,变量的值就被复制,之后即使外部变量的值发生改变,Lambda 内部使用的仍是捕获时的值。
#include
int main() {
int x = 10;
auto lambda = [x]() {
std::cout << "Captured value of x: " << x << std::endl;
};
x = 20;
lambda(); // 输出 10
return 0;
}
引用捕获会存储外部变量的引用,而不是副本。这意味着 Lambda 内部对变量的修改会影响到外部变量,反之亦然。
#include
int main() {
int x = 10;
auto lambda = [&x]() {
std::cout << "Captured reference of x: " << x << std::endl;
x = 20;
};
lambda(); // 输出 10
std::cout << "Value of x after lambda: " << x << std::endl; // 输出 20
return 0;
}
可以同时使用值捕获和引用捕获,用逗号分隔不同的捕获方式。
#include
int main() {
int x = 10;
int y = 20;
auto lambda = [x, &y]() {
std::cout << "Captured value of x: " << x << std::endl;
std::cout << "Captured reference of y: " << y << std::endl;
y = 30;
};
lambda();
std::cout << "Value of y after lambda: " << y << std::endl; // 输出 30
return 0;
}
#include
int main() {
int x = 10;
int y = 20;
auto lambda1 = [=]() {
std::cout << "Captured values: x = " << x << ", y = " << y << std::endl;
};
auto lambda2 = [&]() {
std::cout << "Captured references: x = " << x << ", y = " << y << std::endl;
x = 30;
y = 40;
};
lambda1();
lambda2();
std::cout << "Values after lambda2: x = " << x << ", y = " << y << std::endl;
return 0;
}
在 Qt 中,信号与槽机制是处理事件的核心。Lambda 表达式可以作为槽函数使用,使得代码更加简洁。
#include
#include
#include
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget window;
QPushButton button("Click me", &window);
int counter = 0;
QObject::connect(&button, &QPushButton::clicked, [&counter]() {
counter++;
std::cout << "Button clicked " << counter << " times." << std::endl;
});
window.show();
return app.exec();
}
在这个例子中,我们创建了一个 QPushButton
,并使用 QObject::connect
将其 clicked
信号连接到一个 Lambda 表达式。每次按钮被点击时,Lambda 表达式会将 counter
变量加 1 并输出点击次数。由于使用了引用捕获,Lambda 内部可以修改外部的 counter
变量。
QTimer
中使用 QTimer
是 Qt 中用于定时触发事件的类,Lambda 表达式可以方便地作为定时器的槽函数。
#include
#include
#include
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
int counter = 0;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&counter]() {
counter++;
std::cout << "Timer ticked " << counter << " times." << std::endl;
if (counter >= 5) {
QCoreApplication::quit();
}
});
timer.start(1000); // 每秒触发一次
return app.exec();
}
在这个例子中,我们创建了一个 QTimer
,并将其 timeout
信号连接到一个 Lambda 表达式。定时器每秒触发一次 timeout
信号,Lambda 表达式会将 counter
变量加 1 并输出计时次数。当 counter
达到 5 时,程序退出。