一、为什么要使用匿名函数lamdba
首先,lambda表达式可以使代码变得简单,C++中,一个lambda表达式表示一个可调用的代码单元。如代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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(); } |
如上,对于一个简单的计算,我们可以通过定义函数的形式,或者使用匿名函数的方法来实现。当然,如果这个函数功能十分简单,不会被重复使用,又不至于单独写一个函数,可以通过匿名函数简化代码:
1 2 3 4 | 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; |
如上可以简单的示例简化的作用。
二、匿名函数中于外部的交互
1 2 | int n = 2; qDebug()<<[n]( int n1){ return n1+n;}(3)<<endl; |
如上,方括号[]用来传递局部变量,可在[]内枚举函数体内需要用到的局部变量。使用[=]则外部的所有变量函数体内都可使用。同理[&]用引用的方法也相同,但是如果需要引用的变量是动态的,例如指针,则这种方法可能会引发出错,内存释放不及时,导致其他变量的值出错。[this]这也类似,都能使用函数体外部的变量。
如果想要修改操作外面的变量:
1 2 3 | int n = 2; qDebug()<<[&]( int n1){n = 3; return n1+n;}(3)<<endl; //6 qDebug()<<n<<endl; //3 |
注意,[] 里面获取n和通过=获取所有的变量都只是只读的,不能修改!!!如果只是想要内部修改,不改变局部变量实际值的话,可以通过关键字 mutable实现:
1 2 3 | int n = 2; qDebug()<<[=]( int n1) mutable {n = 3; return n1+n;}(3)<<endl; //6 qDebug()<<n<<endl; //2 |
三、匿名函数在connect中的使用
事实上,匿名函数作为一个槽函数是非常方便的。
1 2 3 4 5 6 7 8 9 10 11 12 | 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的使用,如果是类中的变量的话,是可以修改的,如果是局部变量是修改不了的,代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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。
1 2 3 4 5 6 7 8 9 10 11 | 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为局部变量的话:
1 2 3 4 5 6 7 8 9 10 11 | 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 } |
作者:禅在心中
出处:http://www.cnblogs.com/pinking/
本文版权归作者和博客园共有,欢迎批评指正及转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步