Capturing pointers in lambda expression?

c++, c++11, lambda

Solution

However, the data pointed to can be changed and there is no way to change this, because const is not allowed in the lambda capture.

No, when capturing by value in a lambda expression constness is preserved, i.e. capturing a pointer to `const` data will prevent changes to the data inside the lambda.

int i = 1;
const int* ptr = &i;

auto func = [ptr] {
    ++*ptr; // ERROR, ptr is pointer to const data.
}

A lambda will also add top-level constness to pointers when capturing by value (unless using `mutable`).

auto func = [ptr] {
    ptr = nullptr; // ERROR, ptr is const pointer (const int* const).
}

auto func = [ptr] () mutable { // Mutable, will not add top-level const.
    ptr = nullptr; // OK
}

I can use the second signature, but I cannot protect the data from being changed in the lambda expression.

You can protect the data from being changed inside the lambda by using `const`.

const Bar* bar = &bar_data;
auto b = [bar] (const Bar* element) { // Data pointed to by bar is read-only.
    return bar == element;
};

Also the lambda expression takes a parameter of type `const Bar* const &`, i.e. reference to const pointer to const data. No need to take a reference, simply take a `const Bar*`.

More info about pointers and `const`: What is the difference between const int*, const int * const, and int const *?

Problem

I have a function that uses a lambda expression. ``` std::vector<Bar*> mBars; void foo(Bar* bar) { auto duplicateBars = std::remove_if(mBars.begin(), mBars.end(), [bar] (const Bar* const &element) { return bar == element; }); mBars.erase(duplicateBars, mBars.end()); } ``` Later, I reviewed the code and realized I could add two consts to foo's signature. ``` void foo(const Bar* const bar); ``` `bar`'s pointer and data is now constant, but for the purpose of the lambda expression the pointer itself is constant, because I captured by value. However, the data pointed to can be changed and there is no way to change this, because `const` is not allowed in the lambda capture. This is unintuitive to me. Is my interpretation correct? I can use the second signature, but I cannot protect the data from being changed in the lambda expression.

Original source

Related problems