我正在学习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);
考虑一下这种情况
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