C++ const_iterator 转换为 forward_list 的 iterator

4
根据这个问题,并假设我拥有对容器本身的可变引用,可以使用以下方法安全地去除迭代器的常量性:
foo::const_iterator cit = ... ;
foo::iterator it = c.erase( cit, cit );

然而,对于forward_list的相应函数erase_after来说,似乎并不起作用,如以下代码所示:
#include <iostream>
#include <forward_list>

typedef std::forward_list<int>::const_iterator CIT;
typedef std::forward_list<int>::iterator IT;

int main()
{
    std::forward_list<int> m{1, 2, 3};

    CIT cit = m.begin();
    IT it = m.erase_after(cit, cit); // Segmentation fault!

    std::cout << *it;
}

那么有没有办法在这个类中移除const迭代器的constness呢?最好不要通过迭代来实现!


为什么const_iterator没有像reverse_iterator一样提供一个基类? - underscore_d
3个回答

5
你出现了“段错误”,是因为你违反了erase_after()函数的前置条件。这个函数要求传入的区间(first, last)必须满足特定条件。
iterator erase_after(const_iterator first, const_iterator last);

应该是一个有效的范围。请注意,这是一种()类型的范围,而不是[),因此两端都被排除在外。这就是为什么(cit, cit)对于erase_after不是一个有效的范围。

使用-D_GLIBCXX_DEBUG的GCC报错:

错误:函数需要一个有效的迭代器范围(__pos,__last),其中__pos应该在__last之前且不等于__last


2

虽然我认为这很棘手,STL应该提供一种正常的方法来解决这个问题,但也有一种解决方案是通过insert_after实现的,因为:

iterator insert_after(const_iterator position, size_type n, const T& x);

前置条件:位置为before_­begin()或是范围在[begin(), end())内的可解引用迭代器。
效果:在位置后插入nx的副本。
返回值:指向最后一个插入的x的迭代器,如果n == 0,则返回position本身。
如果你不想创建T类型的临时对象,可以使用:
template<class InputIterator>
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);

或者

iterator insert_after(const_iterator position, initializer_list<T> il);

并提供一个空序列或初始化列表。

1
@Evg 他只是想将 const_iterator 转换为 iterator,为什么一定要用 erase_after?实际上没有其他方法可以使用 erase_after - RedFog

-2

通过迭代,您可以这样做:

IT it (m.begin());
for ( CIT cit = m.begin(); cit != m.end(); ++cit )
{
   std::advance (it, std::distance<CIT>(it, cit ) );
   // do changes on it
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接