C++11 Lambda的變量捕獲和Lambda在Qt中的應用

一、Lambda


Lambda一般格式是:
[capture](param) mutable ->return-type {body}


這裏主要複習一下Lambda中的capture
lambda中有個閉包的概念,也就是C這類語言中的域的概念,要訪問閉包外的變量,就必須通過 [] 來捕獲
[]的形式有以下
[]               未定義任何變量,不能訪問lambda之外定義的變量
[x, &y]       x是通過值複製來訪問的,y通過引用訪問
[&]             能通過引用訪問外部所有變量
[=]              外部變量都是通過值複製來訪問
[&, x]          x通過值複製訪問,其他變量通過引用訪問
[=, &z]       z通過引用訪問,其他變量通過值捕獲
   
這裏有兩個例子
int x=0;
int y = 42;
auto fun = [x, &y] {
    std::cout<<"x: "<<x<<std::endl;
    std::cout<<"y: "<<y<<std::endl;
    y++;
}


x = y = 77;
fun();
fun();
std::cout<<"final y: "<<y <<std::endl;


輸出結果爲
x: 0
y: 77
x: 0
y: 78
final y: 79


這個例子很好理解,因爲y是用引用傳遞的,在lambda中的改變也會反映到外部變量中,而x只是值傳遞,在lambda中只讀


另一個例子
int id = 0;
auto fun = [id]() mutable {
    std::cout<<"id: "<<id<<std::endl;
    id++;
}
id = 42;
fun();
fun();
fun();
std::cout<<"id"<<std::endl;


輸出結果爲:
id: 0
id: 1
id: 2
42


這個例子中,在lambda的聲明中使用了mutable。
在使用了mutable的lambda中,對象通過值傳遞,但可以在函數內部修改捕獲變量的值。
有趣的是這個改變不會反映到外部變量
這非常類似不同函數總的靜態變量


這裏還要考慮一下lambda的類型問題
因爲lambda是匿名函數對象,所以任何兩個lambda的類型都不同。
在c++11中可以使用auto或者使用template來定義某lambda的類型,或者使用decltype()來獲取類型
eg
std::function<int(int, int)> returnLambda() {
    return [](int x, int y) {
        return x*y;
    }
}






二、在Qt中的應用
在Qt中主要用在槽函數中
eg.
connect(sender, &Sender::enabled, [=](bool enbaled) {
    ...
});

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章