捕获lambda表达式中的指针?

use*_*130 4 c++ lambda c++11

我有一个使用lambda表达式的函数.

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());
}
Run Code Online (Sandbox Code Playgroud)

后来,我查看了代码并意识到我可以为foo的签名添加两个consts.

void foo(const Bar* const bar);
Run Code Online (Sandbox Code Playgroud)

bar现在指针和数据是常量,但是为了lambda表达式的目的,指针本身是常量,因为我按值捕获.但是,指向的数据可以更改,并且无法更改此数据,因为constlambda捕获中不允许这样做.

这对我来说不直观.我的解释是否正确?我可以使用第二个签名,但我无法保护数据不被lambda表达式更改.

Snp*_*nps 9

但是,指向的数据可以更改,并且无法更改此数据,因为lambda捕获中不允许使用const.

不,当在lambda表达式中捕获值时,保留constness,即捕获指向const数据的指针将阻止对lambda内部数据的更改.

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

auto func = [ptr] {
    ++*ptr; // ERROR, ptr is pointer to const data.
}
Run Code Online (Sandbox Code Playgroud)

当按值捕获时,lambda还会为指针添加顶级常量(除非使用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
}
Run Code Online (Sandbox Code Playgroud)

我可以使用第二个签名,但我无法保护数据不被lambda表达式更改.

您可以使用保护数据在lambda内部不被更改const.

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

lambda表达式也采用类型的参数const Bar* const &,即引用 const指向const数据的指针.无需参考,只需拿一个const Bar*.

有关指针的更多信息const:const int*,const int*const和int const*之间有什么区别?

  • @ user870130只有在打算从lambda内部修改传递给lambda的指针时,才能将*reference*传递给指针.在你的情况下你只检查指针相等,所以`const Bar*`就足够了. (2认同)