我如何重构一个方法来擦除基于反向迭代器的元素以避免触发有关复制单个迭代器的警告?

问题描述 投票:0回答:1

我有一个方法,它接受一个 stl 反向迭代器,做一些工作,擦除元素,然后返回一个指向下一个元素的迭代器。例如:

#include <vector>
std::vector<int> int_vector;
using ReverseIteratorType = decltype(int_vector)::reverse_iterator;

void do_stuff();

ReverseIteratorType erase_with_reverse_iter(ReverseIteratorType iter)
{
    do_stuff();
    std::advance(iter, 1);
    int_vector.erase(iter.base());
    return iter;
}

编译时不会出现警告,并且看起来工作正常。问题是,当使用 libstdc++ 运行此代码以验证每个迭代器在使用时是否有效时,如果

iter
指向集合的最后一个元素,则会引发异常,因为迭代器在擦除后被视为单个迭代器,并且不允许调用单个迭代器的复制构造函数。 (这里的另一篇文章对这个问题有更深入的解释。).

godbolt 示例在此演示了该问题

两个问题

  1. 禁止复制单个迭代器是否违反了标准,或者这是 libstdc++ 的健全性检查?
  2. 您将如何重构以避免这个问题?
c++ iterator libstdc++
1个回答
0
投票

你不应该忽略

erase()
的返回值。

erase()
使擦除元素处及其之后的元素的迭代器(以及指针和引用)无效(按容器顺序,而不是迭代器顺序。这包括作为参数传入的迭代器。

© www.soinside.com 2019 - 2024. All rights reserved.