std::prev 和 std::next 对 std::list 的有效性

Validity of std::prev and std::next for std::list

我正在将迭代器存储到列表中:

list<int> l;
l.push_back(21); l.push_back(1); l.push_back(31); l.push_back(41);

auto it = l.find(21);

在我的算法中,每当删除一个节点时,我都需要将相邻的元素相加。像这样:

auto prev = std::prev(it);
auto next = std::next(it);
*prev = *prev + *next;
l.erase(it);

如你所见,我需要确保所有的边界条件。如果:

std::prev()std::next() return 的值是什么

What values do std::prev() and std::next() return...

它们 return 迭代器 it 的第 n 个(其中 n 默认为 1)前导或后继。请参阅此处了解 [iterator.operations] /6 和 /7。

... if they are the first and last elements; or if it itself has become invalid at some point?

调用前迭代器必须有效。如果 it 是相应的边界迭代器之一,则 return 值将是无效迭代器;即 it == begin() 代表 prev(it)it == end() 代表 next(it).

在将 it 用作 prev()next() 的参数之前,需要确定其有效性。 std::prev() and std::next() 不知道为什么要确定迭代器递减或递增是否会将迭代器放在容器的边界之外。

因此,听起来您需要在算法的擦除部分为两个边界条件编写代码;第一个是 it == l.begin(),第二个是 it == prev(l.end()),如果找不到元素,则可能是第三个(因此 it == l.end())。

// only proceed it something is found...
if (it != l.end()) {
  if (it == l.begin()) {
    // nothing to do...? element removed is the first one
  }
  else if (it == std::prev(l.end()) {
    // nothing? element removed is the last one....
  }
  else {
    auto prev = std::prev(it);
    auto next = std::next(it);
    *prev = *prev + *next;
  }
  l.erase(it); // remove the found element...
}