捕获列表中的 C++ lambda 复制值

Posted

技术标签:

【中文标题】捕获列表中的 C++ lambda 复制值【英文标题】:C++ lambda copy value in capture-list 【发布时间】:2014-11-07 18:46:54 【问题描述】:

我有一个程序如下:

int main()

    int val = 4;
    auto add = [val](int a)->int
        val += 2;
        return a+val;
    ;
    cout << add(3) << endl;
    cout << val << endl;
    return 0;

Xcode 中存在编译错误:无法分配给通过非可变 lambda 中的副本捕获的变量。

我的问题是:如果我们选择使用副本(使用“=”或值名称),不能为这个值分配新值或更改吗?

【问题讨论】:

Why does C++0x's lambda require "mutable" keyword for capture-by-value, by default? 的可能重复项 【参考方案1】:

在 lambda 中,捕获的变量默认是不可变的。这不取决于捕获的变量或以任何方式捕获它们的方式。相反,闭包类型的函数调用运算符声明为const

此函数调用运算符或运算符模板声明为const (9.3.1) 当且仅当 lambda 表达式的 parameter-declaration-clause 后面没有mutable

因此,如果你想让捕获的变量在体内可以修改,只需将 lambda 更改为

auto add = [val] (int a) mutable -> int 
    val += 2;
    return a+val;
;

所以const-说明符被删除。

【讨论】:

【参考方案2】:

lambda 的 operator () 隐含为 const,除非 lambda 声明为 mutable - 并且您不能修改 const 成员函数中的数据成员。无论捕获的类型如何,都会发生这种情况。

【讨论】:

【参考方案3】:

只需通过引用捕获它,它就会起作用!

 auto add = [&val](int a) -> int 
       //

【讨论】:

拜托,没有人这样做。它会一直工作到爆炸为止。 @Steazy 为什么会爆炸? 如果val 引用的对象超出范围,这将“爆炸”。例如,当您从函数返回 lambda 时,可能就是这种情况。

以上是关于捕获列表中的 C++ lambda 复制值的主要内容,如果未能解决你的问题,请参考以下文章

循环中的 Lambda 变量捕获 - 这里会发生啥? [复制]

如何将嵌套字典列表与它们的值中的公共键相加? [复制]

第13课 lambda表达式

移动 lambda:一旦你移动捕获了只移动类型,如何使用 lambda? [复制]

C++ lambda表达式(函数指针和function)

C++ Lambda 表达式:通过 ref 开销捕获