std::p rev 和 std::next for std::list 的有效性

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

本文关键字:std list 有效性 for rev next      更新时间:2023-10-16

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

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()返回哪些值:

  • 它们是第一个和最后一个元素;
  • 或者it本身在某个时候变得无效?

std::prev()std::next()返回哪些值...

它们返回迭代器it的第n个(其中n默认为 1)的前置或后继。有关 [iterator.operations]/6 和/7,请参见此处。

。如果它们是第一个和最后一个元素;或者it本身在某个时候变得无效?

在进行调用之前,迭代器需要有效。如果返回值是it是相应的边界迭代器之一,则返回值将是无效的迭代器;即it == begin()prev(it)it == end()next(it)

在将it用作prev()next()的论据之前,需要确定其有效性。std::prev()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...
}