'lambda capture by value mutable doesn't work with const &?

Consider the following:

void test( const int &value )
{
    auto testConstRefMutableCopy = [value] () mutable {
        value = 2; // compile error: Cannot assign to a variable captured by copy in a non-mutable lambda
    };

    int valueCopy = value;
    auto testCopyMutableCopy = [valueCopy] () mutable {
        valueCopy = 2; // compiles OK
    };
}

Why is the first version a compile error when I've declared the lambda as mutable and captured value by value (which I thought made a copy of it)?

Tested with clang (x86_64-apple-darwin14.3.0), which is where the error message comes from, and Visual C++ (vc120).



Solution 1:[1]

mutable allows a lambda to modify copy of a non-const parameter captured by copy, but it does not allow it for const parameters.

So this code works (and outputs inside 2 outside 1):

int a = 1;
[a]() mutable {
    a = 2; // compiles OK
    cout << "inside " << a << "\n";
}();
cout << " outside " << a << "\n";

But if we omit mutable, or make a const int, the compiler gives an error.

In our case, the first lambda gives an error because value is const:

void test( const int &value )

If we make copyValue const:

const int valueCopy = value;

then the same error will occur with the second lambda.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1