我正在学习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

08-24 16:54