使用迭代器调用擦除与const_iterator [英] Calling erase with iterator vs const_iterator
问题描述
为什么调用 const_iterator
的容器的擦除
成员函数失败?
Why does calling the erase
member function of a container with a const_iterator
fail?
它适用于一个非const iterator
。
It works with a non const iterator
.
推荐答案
这不编译,因为 container :: iterator
和 container :: const_iterator
是两种不同的类型并且唯一(一个参数)的擦除版本是: iterator erase(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);
不接受 const_iterator
可以被视为语言标准的缺陷: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf
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
没有这个限制的特殊原因。迭代器仅用于在(可修改)容器中表示位置,并且在插入
或
是迭代器修改的pintee(在 erase
的情况下,它只是在概念上不再存在,这是一个正常的事情const对象)
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).
当前标准表示迭代器常量和容器常量之间的混淆(和其他答案一样),似乎 const_iterator
可能会被C ++ 0x中的 erase
所接受。
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.
作为解决方法,您可以从 const_iterator
中有效地获取 iterator
,因为容器有首先是可变的。
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;
}
}
}
但是,可能会更好重组代码,以便您首先不需要 const_iterator
。在这种情况下,最好使用 std :: remove
算法。如果您需要在删除之前进行更多的非突变工作,则可以将其提取到单独的方法等中。
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.
这篇关于使用迭代器调用擦除与const_iterator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!