[英]Why is erasing via a const_iterator allowed in C++11?
从GCC 4.9.2开始,现在可以编译通过const_iterator插入或删除容器元素的C ++ 11代码。
我可以看到插入接受const_iterator是多么有意义,但我很难理解为什么允许通过const_iterator进行擦除是有意义的。
此问题已在前面讨论过 ,但我没有看到行为改变背后的基本原理的解释。
我能想到的最好的答案是改变的目的是使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模仿这种行为是件好事。
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 ^^^^^
这里的第一个问题是迭代器的常量是否应该暗示整个容器的constnes或者只是迭代的元素的constness。
显然,已经确定后者是正确的方法。 迭代器的常量并不意味着容器的常量,它只意味着容器元素的常量。
从一开始,对象的构造及其对称的对应物 - 对象的破坏 - 被认为是关于对象本身的元操作。 对于这些操作,对象一直被认为是可变的,即使它被声明为const
。 这就是您可以在其构造函数和析构const
中合法修改const
对象的原因。 这是您可以通过const T *
指针delete
类型T
的对象的原因。
鉴于1提到的分辨率,很明显2也应该扩展到迭代器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.