2015-07-02 37 views
13

我構建了一個lambda函數,它需要訪問上下文中相當數量的變量。在lambda捕獲列表中傳遞常量引用

const double defaultAmount = [&]{ 
    /*ToDo*/ 
}(); 

我寧願不在列表中使用[=],因爲我不希望結交了很多價值副本做。

如果我使用[&],我很關心程序的穩定性,因爲我不想讓lambda修改捕獲集。

我可以通過const引用嗎? [const &]不起作用。

也許一個好的編譯器優化了值副本,所以[=]是可取的。

+0

這些是局部變量還是成員變量?你使用什麼編譯器? – MikeMB

+0

兩者都有。我正在使用MSVC2012,並且應該編寫與新g ++編譯的代碼。 –

回答

11

您可以創建並明確地捕捉常量引用:

int x = 42; 
const int& rx = x; 
auto l = [&rx]() { 
    x = 5; // error: 'x' is not captured 
    rx = 5; // error: assignment of read-only reference 'rx' 
}; 
2

不幸的是,C++ 11語法不允許這樣做,所以不行。

+0

如果子程序需要「在上下文中有相當數量的變量」,則做出正確的功能並將它們全部傳遞可能正是OP試圖避免的。 – Angew

2

可以捕獲一個恆定的對象引用,而不是對象本身:

A a; 
const A& ref_a = a; 

const double defaultAmount = [&]{ 
    ref_a.smth(); 
}(); 
7

捕獲列表中有什麼可以限制被抓獲;基本上按值或按參考(命名或默認),this指針和什麼都沒有。

來自cppreference;

捕獲列表 - 一個以逗號分隔的零個或多個捕獲列表中,任選一個捕獲默認開始。捕獲列表可以傳遞如下(見下文的詳細描述):

  • [a,&b]其中a由值捕獲並b通過引用捕獲。
  • [this]由值捕獲this指針
  • [&]捕獲所有自動變量ODR使用的由參考
  • [=]在lambda體捕獲所有自動變量ODR-用於體內按價值計算的拉姆達
  • []無捕獲

您可以創建本地const&到您希望捕獲的所有對象,並使用lambda中的對象。

#include <iostream> 

using namespace std; 

int main() 
{ 
    int a = 5; 
    const int& refa = a; 
    const int b = [&]() -> int { 
     //refa = 10; // attempts to modify this fail 
     return refa; 
    }(); 
    cout << a << " " << b << endl; 
} 

捕獲可能是所有的引用或明確的列表需要什麼;

const int b = [&refa]() 

另一種選擇是不捕獲局部變量。然後創建一個lambda,它接受你需要的變量作爲參數。隨着本地變量計數的增長,這可能會更加努力,但是您可以更多地控制lambda接受其參數的方式並能夠使用數據。

auto lambda = [](const int& refa /*, ...*/) { */...*/ } 
lambda(...); 
相關問題