通过lambda捕获列表中的常量引用传递

时间:2015-07-02 08:28:29

标签: c++ c++11 lambda

我正在构建一个lambda函数,需要在上下文中访问相当数量的变量。

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

我不想在列表中使用[=]因为我不想要制作很多有价值的副本。

如果我使用[&],我担心程序的稳定性,因为我不希望lambda修改捕获集。

我可以通过const引用传递吗? [const &]不起作用。

也许一个好的编译器会优化值副本,所以[=]更可取。

4 个答案:

答案 0 :(得分:15)

您可以明确地创建和捕获const引用:

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'
};

答案 1 :(得分:8)

捕获列表限制在可以捕获的内容中;基本上是按值或按引用(命名或默认),this指针,没有。

来自cppreference;

  

capture-list - 以逗号分隔的零个或多个捕获列表,可选择以 capture-default 开头。捕获列表可以如下传递(详见下面的详细说明):

     
      
  • [a,&b] 其中a按值捕获,b通过引用捕获。
  •   
  • [this] 按值捕获this指针
  •   
  • [&] 通过引用捕获lambda正文中使用的所有自动变量
  •   
  • [=] 按值列出lambda正文中使用的所有自动变量
  •   
  • [] 无法捕获任何内容
  •   

您可以为要捕获的所有对象创建本地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(...);

答案 2 :(得分:2)

可悲的是,C ++ 11语法不允许这样做,所以没有。

答案 3 :(得分:2)

您可以捕获对象的常量引用,而不是对象本身:

$news_users_data = @json_decode(file_get_contents("http://athavannews.com/?page_id=232365&datefrom=2015-07-02+00:00:00&dateto=2015-07-02+23:59:59"), true);

print_r($news_users_data);
foreach($news_users_data as $data){
    if($data['post_count'] != 0){
        echo "<pre>";
        print_r($data);
        echo "</pre>";
    }
}