Lambda
Lambda函数也叫匿名函数,是自定义函数的一种,专指用关键字” lambda”定义的无名短函数,所以也有Lambda表达式这种说法。这种函数得名于省略了用def声明函数的标准步骤,是C++ 11中新增的特性;
C++ 中的 Lambda 表达式
是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象(闭包)的简便方法。 Lambda 通常用于封装传递给算法或异步函数的少量代码行;
使用Lambda函数的好处
零成本抽象。对!你没有看错。Lambda函数不会降低性能,它的性能和普通的函数一样好。
此外,Lambda函数使代码变得更加紧凑、更加结构化和更富有表现力;
lambda在c++价值体现
lambda在c++作用主要是作为内嵌函数,逻辑更加清楚,代码可读性更好
老的方式:
void hello()
{
printf("hello ...");
}
void main()
{
thread t1(hello);
t1.join();
}
lambda方式
void main()
{
thread t1([]() {
printf("hello...");
});
t1.join();
}
Lambda 表达式的各个部分
ISO C++ 标准展示了作为第三个参数传递给 std::sort()
函数的简单 lambda:
#include <algorithm>
#include <cmath>
void abssort(float* x, unsigned n) {
std::sort(x, x + n,
// Lambda expression begins
[](float a, float b) {
return (std::abs(a) < std::abs(b));
} // end of lambda expression
);
}
此图显示了 lambda 的组成部分:
-
capture 子句(在 C++ 规范中也称为 Lambda 引导。)
-
参数列表(可选)。 (也称为 Lambda 声明符)
-
mutable 规范(可选)。
-
exception-specification(可选)。
-
trailing-return-type(可选)。
-
Lambda 体。
具体见:
C++ 中的 Lambda 表达式 | Microsoft Learn
Qt lambda
因为lambda表达式是c++11的特性
注意:pro文件中 需要添加
config+=c++11
语法形式如下:
[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}
可以看到,Lambda 主要分为五个部分:[函数对象参数]、(操作符重载函数参数)、mutable 或 exception 声明、-> 返回值类型、{函数体}.
常见的lambda表达式使用(qt线程)
QThread * th=QThread::create([=]{
qDebug()<<"test";
});
connect(th,&QThread::destroyed,th,&QThread::deleteLater);
th->start();
看这个是不是和 Android 按钮点击很像,匿名函数
QPushButton* btn=new QPushButton(this);
b4->setText("click this");
connect(btn,&QPushButton::clicked,
[=](bool isCheck) mutable //isCheck接受clicked()函数返回值
{
qDebug()<<"isCheck";
}
);
按钮被点击后输出
isCheck
QCheckBox checkBox
QCheckBox checkBox;
connect(&checkBox, static_cast<void(QCheckBox ::*)(bool b)>(&QCheckBox::clicked), [=](bool b) {
emit this->slot_check_btn(b);
});
QTimer lambda
m_timer = new QTimer();
m_timer->start(1000);
connect(m_timer,&QTimer::timeout, this, [=]()mutable{
qDebug() << "timeout";
});
void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
这个静态函数在一个给定时间间隔 msec(毫秒) 之后调用一个槽。
QTimer::singleShot(1000, this, [&]()
{
dosomething();
});
但是为了让循环可控,应该加个条件
bool condition = true;
function(){
if(condition){
QTimer::singleShot( 1000,this, &AClass::function());
}
}
QThread pool 线程池
workcase.h
#ifndef WORKCASE_H
#define WORKCASE_H
#include <QObject>
#pragma execution_character_set("utf-8")
class WorkCase : public QObject
{
Q_OBJECT
signals:
void test1(const QString& str);
void test2(const QString& str);
public slots:
};
#endif // WORKCASE_H
mian.cpp
#include <QCoreApplication>
#include <QCoreApplication>
#include <QThreadPool>
#include <QtConcurrent/QtConcurrent>
#include <QThread>
#include <QDebug>
#include "workcase.h"
inline void printTID(const QString& str="")
{
qDebug() << QThread::currentThreadId() << str;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WorkCase* test = nullptr;
QThreadPool pool;
printTID(":this is main thread");
QtConcurrent::run(&pool, [&test](){
test = new WorkCase;
printTID(":t1");
QEventLoop e;
QObject::connect(test, &WorkCase::test1, test/*lambda表达式执行在创建该对象的线程中*/,[](const QString& str){
printTID(":this is t1 thread " + str);
});
QObject::connect(test, &WorkCase::test2/*lambda表达式执行在创建信号发射对象的线程中*/, [](const QString& str){
printTID(":我在t2或t3中执行" + str);
});
e.exec();
});
QtConcurrent::run(&pool, [&test](){
printTID(":t2");
while(1)
{
if(nullptr != test)
{
emit test->test1("from t2");
emit test->test2("from t2");
}
QThread::msleep(1000);
}
});
QtConcurrent::run(&pool, [&test](){
printTID(":t3");
while(1)
{
if(nullptr != test)
{
emit test->test1("from t3");
emit test->test2("from t3");
}
QThread::msleep(1000);
}
});
while(1)
{
QThread::msleep(1000);
}
return 0;
}