list.erase 中的 Lambda 表达式

Lambda expression in list.erase

我正在学习 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 一起存储。由于 std::find(listIntegers.begin(), listIntegers.end(), 40) 中使用的 listIntegers 是原件的副本,它将在该副本中找到元素 40。因此,returned 迭代器是副本中元素的迭代器,而不是原始元素中的迭代器。迭代器只能与来自同一容器的其他迭代器及其原始容器一起使用。您看到的问题是您的 lambda 的 return 值正在与 listIntegers 一起使用,但它实际上指的是不同范围内的元素(listIntegers 的副本)。

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

listIntegers.erase([&listIntegers]() {
    // Added & here ^
    return std::find(listIntegers.begin(), listIntegers.end(), 40);
}());
//^ Call the lambda