我正在学习lambda,并正在尝试各种示例,但不确定是否明白为什么这行不通:
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);
最佳答案
考虑情况
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