简体   繁体   English

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

[英]Why is erasing via a const_iterator allowed in C++11?

As of GCC 4.9.2, it's now possible to compile C++11 code that inserts or erases container elements via a const_iterator. 从GCC 4.9.2开始,现在可以编译通过const_iterator插入或删除容器元素的C ++ 11代码。

I can see how it makes sense for insert to accept a const_iterator, but I'm struggling to understand why it makes sense to allow erasure via a const_iterator. 我可以看到插入接受const_iterator是多么有意义,但我很难理解为什么允许通过const_iterator进行擦除是有意义的。

This issue has been discussed previously , but I haven't seen an explanation of the rationale behind the change in behaviour. 此问题已在前面讨论过 ,但我没有看到行为改变背后的基本原理的解释。

The best answer I can think of is that the purpose of the change was to make the behaviour of const_iterator analogous to that of a const T*. 我能想到的最好的答案是改变的目的是使const_iterator的行为类似于const T *的行为。

Clearly a major reason for allowing delete with const T* is to enable declarations such as: 显然允许使用const T *删除的一个主要原因是启用声明,例如:

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

However, it also permits the following less desirable behaviour: 但是,它还允许以下不太理想的行为:

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

and I'm struggling to see why it's a good thing for const_iterator to emulate this behaviour. 而且我很难理解为什么const_iterator模仿这种行为是件好事。

erase and insert are non- const member functions of the collection. eraseinsert是集合的非const成员函数。 Non-const member functions are the right way to expose mutating operations. 非const成员函数是公开变异操作的正确方法。

The constness of the arguments are irrelevant; 论证的常数是无关紧要的; they aren't being used to modify anything. 它们不被用来修改任何东西。 The collection can be modified because the collection is non- const (held in the hidden this argument). 可以修改集合,因为集合是非const (保存在隐藏的this参数中)。

Compare: 相比:

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

to a similar overload that is NOT allowed 到一个不允许的类似重载

template <typename T>
std::vector<T>::iterator std::vector<T>::erase( std::vector<T>::iterator pos ) const;
                                                                         wrong ^^^^^
  1. The first question here is whether constness of an iterator is supposed to imply constnes of the entire container or just constness of the elements being iterated over. 这里的第一个问题是迭代器的常量是否应该暗示整个容器的constnes或者只是迭代的元素的constness。

    Apparently, it has been decided that the latter is the right approach. 显然,已经确定后者是正确的方法。 Constness of an iterator does not imply constness of the container, it only implies constness of container's elements. 迭代器的常量并不意味着容器的常量,它只意味着容器元素的常量。

  2. Since the beginning of times, construction of an object and its symmetrical counterpart - destruction of an object - were considered meta-operations with regards to the object itself. 从一开始,对象的构造及其对称的对应物 - 对象的破坏 - 被认为是关于对象本身的元操作。 The object has always been supposed to behave as mutable with regard to these operations, even if it was declared as const . 对于这些操作,对象一直被认为是可变的,即使它被声明为const This is the reason you can legally modify const objects in their constructors and destructors. 这就是您可以在其构造函数和析构const中合法修改const对象的原因。 This is the reason you can delete an object of type T through a const T * pointer. 这是您可以通过const T *指针delete类型T的对象的原因。

Given the resolution referred to by 1, it becomes clear that 2 should be extended to iterators as well. 鉴于1提到的分辨率,很明显2也应该扩展到迭代器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM