Это не компилируется, потому что container::iterator
и container::const_iterator
- это два разных типа, и единственная (с одним аргументом) версия стирания: iterator erase(iterator);
Не принимать const_iterator
может бытьрассматривается как дефект в языковом стандарте: http://www.open -std.org / jtc1 / sc22 / wg21 / docs / documents / 2007 / n2350.pdf
Нет особых причин дляэто ограничение.Итератор используется только для указания позиции в (изменяемом) контейнере, и ни в случае insert
, ни erase
"pointee" итератора не изменен (в случае erase
он просто концептуально исчезает, что является обычным делом для константных объектов).
Текущий стандарт указывает на путаницу между «константностью итератора и константностью контейнера» (как и другие ответы здесь), и кажется,const_iterator
может стать приемлемым для erase
в C ++ 0x.
В качестве обходного пути вы можете получить iterator
из 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 prevents this error
if (*it == 5) {
it = vec.erase(to_mutable_iterator(vec, it));
}
else {
++it;
}
}
}
Однако онаможет быть, лучше реструктурировать код, чтобы вам не понадобился const_iterator
.В этом случае было бы лучше использовать алгоритм std::remove
.Если перед удалением вам нужно выполнить больше работы без мутаций, вы можете извлечь ее в отдельный метод и т. Д.