C++ lambda 通过父 lambda 捕获值的副本进行捕获

iga*_*gis 10 c++ g++ language-lawyer clang++

尝试编译以下代码:

#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'
        }();
    };

}
Run Code Online (Sandbox Code Playgroud)

给出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’
        }();
    };

}
Run Code Online (Sandbox Code Playgroud)

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

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

clang++ 7.0.1 版本编译成功。

错误g++

ale*_*ame 5

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

可变lambdaa内部的类型是因为它是通过从封闭const 的a 复制捕获的。因此,使两个 lambda 都可变可以解决这个问题。const intconst int a lambda