从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能够模仿这种行为是一件好事。
答案 0 :(得分:8)
erase
和insert
是该集合的非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)
这里的第一个问题是迭代器的常量是否应该暗示整个容器的constnes或者只是迭代的元素的常量。
显然,已经确定后者是正确的方法。迭代器的常量并不意味着容器的常量,它只意味着容器元素的常量。
从一开始,对象的构造及其对称的对称对象 - 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)
对象的原因。
鉴于1提到的解决方案,很明显2也应该扩展到迭代器。