前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Qt中使用匿名函数lambda表达式

Qt中使用匿名函数lambda表达式

作者头像
全栈程序员站长
发布2022-07-09 12:30:41
发布2022-07-09 12:30:41
68900
代码可运行
举报
运行总次数:0
代码可运行

一、为什么要使用匿名函数lamdba

首先,lambda表达式可以使代码变得简单,C++中,一个lambda表达式表示一个可调用的代码单元。如代码:

代码语言:javascript
代码运行次数:0
复制
#include <QCoreApplication>
#include <QDebug>
#include <QSharedPointer>

int func2(int i)
{
   i += 2;
   return i+4;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    auto func1 = [](int i) {i += 2; return i+4; };
    qDebug()<< "func2: " << func2(6) << '\n';
    qDebug()<< "func1: " << func1(6) << '\n';

    return a.exec();
}

  如上,对于一个简单的计算,我们可以通过定义函数的形式,或者使用匿名函数的方法来实现。当然,如果这个函数功能十分简单,不会被重复使用,又不至于单独写一个函数,可以通过匿名函数简化代码:

代码语言:javascript
代码运行次数:0
复制
int result  = 0;
bool isAdd = false;
result = isAdd? [](int a,int b){return a+b;}(10,5):[](int a,int b){return a-b;}(10,5);
qDebug()<<result<<endl;

  如上可以简单的示例简化的作用。

二、匿名函数中于外部的交互

代码语言:javascript
代码运行次数:0
复制
int n = 2;
qDebug()<<[n](int n1){return n1+n;}(3)<<endl;

  如上,方括号[]用来传递局部变量,可在[]内枚举函数体内需要用到的局部变量。使用[=]则外部的所有变量函数体内都可使用。同理[&]用引用的方法也相同,但是如果需要引用的变量是动态的,例如指针,则这种方法可能会引发出错,内存释放不及时,导致其他变量的值出错。[this]这也类似,都能使用函数体外部的变量。

  如果想要修改操作外面的变量:

代码语言:javascript
代码运行次数:0
复制
int n = 2;
qDebug()<<[&](int n1){n = 3;return n1+n;}(3)<<endl;  //6
qDebug()<<n<<endl;  //3

  注意,[] 里面获取n和通过=获取所有的变量都只是只读的,不能修改!!!如果只是想要内部修改,不改变局部变量实际值的话,可以通过关键字 mutable实现:

代码语言:javascript
代码运行次数:0
复制
int n = 2;
qDebug()<<[=](int n1)mutable {n = 3;return n1+n;}(3)<<endl;  //6
qDebug()<<n<<endl;  //2

三、匿名函数在connect中的使用

  事实上,匿名函数作为一个槽函数是非常方便的。

代码语言:javascript
代码运行次数:0
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    int n = 0;
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout,this, [=]()mutable {n += 1;qDebug()<<n<<endl;});
    timer->start(1000);

}

  注意,lamda匿名函数对应的信号必须是函数指针的形式。

  注意:通过mutable的使用,如果是类中的变量的话,是可以修改的,如果是局部变量是修改不了的,代码示例:

代码语言:javascript
代码运行次数:0
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    n = 0;
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout,this, [=]()mutable {n += 1; if(n == 3){timer->stop();}qDebug()<<n<<endl;});
    timer->start(1000);
}
void Widget::on_pushButton_clicked()
{
    qDebug()<<n<<endl;
}

  如上,我对于定时器跳到n为3的时候就停下来,然后按按钮,查看当前的n的值,发现类中属性n为3。

代码语言:javascript
代码运行次数:0
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    n = 0;
    qDebug()<<[=](int n1)mutable {n += 3;return n1+n;}(3)<<endl;  //6
    qDebug()<<n<<endl;  //3

}

  如果n为局部变量的话:

代码语言:javascript
代码运行次数:0
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    int n = 0;
    qDebug()<<[=](int n1)mutable {n += 3;return n1+n;}(3)<<endl;  //6
    qDebug()<<n<<endl;  //0

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/119439.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年11月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档