list.erase中的Lambda表达式

问题描述 投票:1回答:1

我正在学习lambdas并尝试各种各样的例子,我不确定为什么这不起作用:

std::list<int> listIntegers;
listIntegers.push_back(40);

listIntegers.erase([listIntegers]() {
return std::find(listIntegers.begin(), listIntegers.end(), 40);
});

我也尝试明确写:

listIntegers.erase([listIntegers]()->std::list<int>::const_iterator {
    return std::find(listIntegers.begin(), listIntegers.end(), 40);
    });

然而,这当然有效:

auto found40Iterator = std::find(listIntegers.begin(), listIntegers.end(), 40)

listIntegers.erase(found40Iterator);
c++ list lambda stdlist
1个回答
2
投票

考虑一下这种情况

listIntegers.erase([listIntegers]()->std::list<int>::const_iterator {
    return std::find(listIntegers.begin(), listIntegers.end(), 40);
});

捕获列表[listIntegers]按值获取listInteger,副本与lambda一起存储。由于在listIntegers中使用的std::find(listIntegers.begin(), listIntegers.end(), 40)是原件的副本,因此它将在该副本中找到元素40。因此,返回的迭代器是副本中元素的迭代器,而不是原始元素的迭代器。迭代器只能与同一容器中的其他迭代器一起使用,并与原始容器一起使用。您看到的问题是您的lambda的返回值与listIntegers一起使用,但实际上它指的是不同范围内的元素(listIntegers的副本)。

解决方案是更改您的捕获列表以通过引用获取listIntegers,以便它将在原始listIntegers上运行。还有一个问题是你没有调用lambda,而是将它作为参数传递给erase。通过添加一对括号,我们可以调用lambda并将其返回值传递给erase

listIntegers.erase([&listIntegers]() {
    // Added & here ^
    return std::find(listIntegers.begin(), listIntegers.end(), 40);
}());
//^ Call the lambda
© www.soinside.com 2019 - 2024. All rights reserved.