为什么在C ++ 11中允许通过const_iterator进行擦除?

时间:2015-06-17 19:51:37

标签: c++ c++11 stl const delete-operator

从GCC 4.9.2开始,现在可以编译通过const_iterator插入或删除容器元素的C ++ 11代码。

我可以看到插入接受const_iterator是多么合理,但是我很难理解为什么允许通过const_iterator进行擦除是有意义的。

这个问题一直是discussed previously,但我还没有看到对行为改变背后的理由的解释。

我能想到的最佳答案是,改变的目的是使const_iterator的行为类似于const T *的行为。

显然,允许使用const T *删除的一个主要原因是启用声明,例如:

const T* x = new T;
....
delete x;

但是,它还允许以下不太理想的行为:

int** x = new int*[2];
x[0] = new int[2];
const int* y = x[0];
delete[] y; // deletes x[0] via a pointer-to-const

我很难理解为什么const_iterator能够模仿这种行为是一件好事。

2 个答案:

答案 0 :(得分:8)

eraseinsert是该集合的非const成员函数。非const成员函数是公开变异操作的正确方法。

论证的常数是无关紧要的;它们不被用来修改任何东西。可以修改集合,因为集合不是 - const (保存在隐藏的this参数中)。

比较

template <typename T>
std::vector<T>::iterator std::vector<T>::erase( std::vector<T>::const_iterator pos );
                                                                ^^^^^ ok

到不允许的类似重载

template <typename T>
std::vector<T>::iterator std::vector<T>::erase( std::vector<T>::iterator pos ) const;
                                                                         wrong ^^^^^

答案 1 :(得分:0)

  1. 这里的第一个问题是迭代器的常量是否应该暗示整个容器的constnes或者只是迭代的元素的常量。

    显然,已经确定后者是正确的方法。迭代器的常量并不意味着容器的常量,它只意味着容器元素的常量。

  2. 从一开始,对象的构造及其对称的对称对象 - destroy 被认为是关于对象的元操作本身。对于这些操作,对象一直被认为是可变的,即使它被声明为const。这就是您可以在其构造函数和析构函数中合法修改const个对象的原因。这就是delete通过T指针const T * //the unit function makes sure that a random letter is returned but also makes sure that the first letter returned comes before the second letter in the values array function unit(){ var values = ["a", "b", "c", "d", "e" , "f"]; var value1 = Math.floor(Math.random() * (values.length - 1)) + 1; var value2 = Math.floor(Math.random() * value1); if(value1 !== value2){ return [values[value2], values[value1]]; } } //pseusodo-code // i have to do a different operation dependeng on the values of v1 and v2 //bad code function conversion(v1, v2, num){ if(v1 == "a" && v2 == "b"){ return 16 * num } if(v1 == "a" && v2 == "c"){ return 32 * num } if(v1 == "a" && v2 == "d"){ return 64 * num } if(v1 == "a" && v2 == "e"){ return 256 * num } if(v1 == "b" && v2 == "c"){ return 18 * num } if(v1 == "b" && v2 == "d"){ return 20 * num } if(v1 == "b" && v2 == "e"){ return 64 * num } if(v1 == "b" && v2 == "f"){ return 256 * num } etc } function string(){ u = unit() v1 = u[0]; v2 = u[1] return "this is " + v1 + " and this " + v2 } console.log(string()) // for every 2 a theres 1 b's //for every 16 a there 1 c //for every 32 a there is 1 d //for every 64 a there is 1 e conversion(v1,v2, 2.5) console.log(v1, " ", v2) 对象的原因。

  3. 鉴于1提到的解决方案,很明显2也应该扩展到迭代器。