用iterator vs const_iterator调用erase [英] Calling erase with iterator vs const_iterator

查看:296
本文介绍了用iterator vs const_iterator调用erase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么调用 const_iterator 失败的容器的 erase 成员函数?



它适用于一个非const 迭代器

解决方案

这不会编译,因为 container :: iterator container :: const_iterator 并且擦除的唯一(一个参数)版本是:迭代器擦除(迭代器);



不接受 const_iterator 可视为语言标准中的缺陷: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf



这个限制没有特别的原因。迭代器仅用于在(可修改)容器中指示位置,并且在 insert 擦除是迭代器修改的pointee(在 erase 的情况下),它只是概念上不存在,这是一个正常的事情const对象)。



当前标准表示迭代器常量和容器常量之间的混淆(和其他答案一样),似乎 const_iterator 可能会被C ++ 0x中的 erase 接受。





作为解决方法,您可以从 const_iterator 中有效地获取迭代器,因为容器



下面的函数只能编译为随机访问迭代器,因为它可能有点太慢,不能用其他类型的迭代器。

  #include< vector> 

template< class Container>
typename Container :: iterator to_mutable_iterator(Container& c,typename Container :: const_iterator it)
{
return c.begin()+(it - c.begin());
}

int main()
{
int arr [] = {1,5,2,5,3,4,5,1}
std :: vector< int> vec(arr,arr + sizeof(arr)/ sizeof(* arr));
for(std :: vector< int> :: const_iterator it = vec.begin(); it!= vec.end();){
// if(* it = 5){/ / const_iterator防止这个错误
if(* it == 5){
it = vec.erase(to_mutable_iterator(vec,it));
}
else {
++ it;
}
}
}

重构代码,使您不需要 const_iterator 。在这种情况下,最好使用 std :: remove 算法。如果你需要在擦除之前做更多的不变异的工作,你可以提取到一个单独的方法等。


Why does calling the erase member function of a container with a const_iterator fail?

It works with a non const iterator.

解决方案

This doesn't compile because container::iterator and container::const_iterator are two distinct types and the only (one-argument) version of erase is: iterator erase(iterator);

Not accepting a const_iterator can be viewed as a defect in the language standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf

There is no particular reason for this restriction. The iterator is only used to indicate a position in the (modifiable) container, and neither in case of insert or erase is the "pointee" of the iterator modified (in case of erase it just conceptually goes out of existence, which is a normal thing to do for const objects).

Current standard indicates a confusion between "iterator constness and container constness" (as do other answers here), and it seems const_iterator might become acceptable for erase in C++0x.


As a workaround, you can validly obtain an iterator from a const_iterator because the container has to be mutable in the first place.

The function below is only compilable for random access iterators, as it might be a bit too slow to do this with other types of iterators.

#include <vector>

template <class Container>
typename Container::iterator to_mutable_iterator(Container& c, typename Container::const_iterator it)
{
    return c.begin() + (it - c.begin());
}

int main()
{
    int arr[] = {1, 5, 2, 5, 3, 4, 5, 1};
    std::vector<int> vec(arr, arr + sizeof(arr) / sizeof(*arr));
    for (std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ) {
        //if (*it = 5) {  //const_iterator prevents this error
        if (*it == 5) {
            it = vec.erase(to_mutable_iterator(vec, it));
        }
        else {
            ++it;
        }
    }
}

However, it might be better to restructure code so that you don't need a const_iterator in the first place. In this case, it would be better to use the std::remove algorithm. If you need to do more non-mutating work before erasing, you can extract that into a separate method etc.

这篇关于用iterator vs const_iterator调用erase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆