首页 > 解决方案 > 通过父 lambda 捕获值的副本捕获 C++ lambda

问题描述

尝试编译以下代码:

#include <functional>

void test() {

    int a = 5;

    std::function<void()> f = [a](){
        [a]()mutable{ // isn't it capture 'a' by copy???
            a = 13; // error: assignment of read-only variable 'a'
        }();
    };

}

给出error: assignment of read-only variable 'a'错误。

a通过在捕获中添加花括号来更改代码:

#include <functional>

void test() {

    int a = 5;

    std::function<void()> f = [a](){
        [a{a}]()mutable{ // this explicitly copies a
            a = 13; // error: assignment of read-only variable ‘a’
        }();
    };

}

消除编译错误。我想知道为什么会这样?第一个变体不等于第二个变体吗?

这是使用g++Debian 的 8.3.0 版本时。

clang++版本 7.0.1 编译成功。

错误g++

标签: c++g++language-lawyerclang++

解决方案


[C++11: 5.1.2/14]:如果实体被隐式捕获并且捕获默认值为 =,或者如果使用不包含 & 的捕获显式捕获实体,则通过副本捕获实体。对于通过副本捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。这些成员的声明顺序是未指定的。如果实体不是对对象的引用,则此类数据成员的类型是相应捕获实体的类型,否则为引用类型。

可变lambdaa内部的类型是因为它是由封闭const的 a 的副本捕获的。因此,使两个 lambdas 都可变可以解决这个问题。const intconst int a lambda


推荐阅读