C ++ STL中的const_iterator和非const迭代器有什么区别?

const_iteratoriterator之间有什么区别,你会在哪里使用它们?

const_iterator不允许你改变它们指向的值,常规iterator就是这样做的。

和C ++中的所有东西一样,除非有一个很好的理由使用常规迭代器(例如,你想使用它们不是const来改变指向的值),否则总是比较喜欢const

他们应该几乎不言自明。 如果迭代器指向Ttypes的元素,则const_iterator指向“const T”types的元素。

它基本上等同于指针types:

 T* // A non-const iterator to a non-const element. Corresponds to std::vector<T>::iterator T* const // A const iterator to a non-const element. Corresponds to const std::vector<T>::iterator const T* // A non-const iterator to a const element. Corresponds to std::vector<T>::const_iterator 

const迭代器总是指向相同的元素,所以迭代器本身是const的。 但是它指向的元素不一定是const,所以它指向的元素可以改变。 const_iterator是一个指向const元素的迭代器,所以当迭代器本身可以被更新(例如递增或递减)时,指向的元素不能被改变。

不幸的是,很多STL容器的方法都是以迭代器而不是const_iterators作为参数。 所以,如果你有一个const_iterator ,你不能说“在这个迭代器指向的元素之前插入一个元素”(在我看来,这样的事情在概念上并不是一个常量违例)。 如果你想这样做,你必须使用std :: advance()boost :: next()将其转换为非const迭代器。 例如。 boost :: next(container.begin(),std :: distance(container.begin(),the_const_iterator_we_want_to_unconst)) 。 如果容器是一个std :: list ,那么这个调用的运行时间将是O(n)

因此,在STL容器中,添加const的通用规则在“逻辑”的位置添加是不太普遍的。

但是,boost容器需要const_iterators(例如boost :: unordered_map :: erase())。 所以当你使用boost容器时,你可以是“不变的”。 顺便说一下,有谁知道是否或何时STL容器将被固定?

尽可能使用const_iterator ,当没有其他select的时候使用迭代器

(正如其他人所说的),const_iterator不允许修改它指向的元素,这在const类方法中很有用。 它也可以让你expression你的意图。

好吧让我先解释一下非常简单的例子,而不使用常量迭代器考虑我们有随机整数集合“randomData”

  for(vector<int>::iterator i = randomData.begin() ; i != randomData.end() ; ++i)*i = 0; for(vector<int>::const_iterator i = randomData.begin() ; i!= randomData.end() ; ++i)cout << *i; 

可以看出,在集合内写入/编辑数据正常使用迭代器,但是为了读取目的,已经使用了不断的迭代器。 如果你在第一个循环中尝试使用常量迭代器,你将会得到错误。 作为一个拇指规则使用常量迭代器来读取集合中的数据。

最小的例子

非常量迭代器允许您修改它们指向的内容:

 std::vector<int> v{0}; std::vector<int>::iterator it = v.begin(); *it = 1; assert(v[0] == 1); 

Const迭代器不会:

 const std::vector<int> v{0}; std::vector<int>::const_iterator cit = v.begin(); // Compile time error: cannot modify container with const_iterator. //*cit = 1; 

如上所示, v.begin()const重载,并根据容器variables的常量返回iteratorconst_iterator

  • begin()如何知道返回哪个返回types(const或非const)?
  • const和非const函数的重载是如何工作的?

const_iteratorpopup的常见情况是在const方法中使用它的时候:

 class C { public: std::vector<int> v; void f() const { std::vector<int>::const_iterator it = this->v.begin(); } void g(std::vector<int>::const_iterator& it) {} }; 

const使this const,这使得this->v const。

你通常可以用auto来忘记它,但是如果你开始传递这些迭代器,你需要考虑方法签名。

与const和非const类似,您可以轻松地从非const转换为const,而不是相反:

 std::vector<int> v{0}; std::vector<int>::iterator it = v.begin(); // non-const to const. std::vector<int>::const_iterator cit = it; // Compile time error: cannot modify container with const_iterator. //*cit = 1; // Compile time error: no conversion from const to no-const. //it = ci1; 

使用哪一个:类似于const int vs int :只要你可以使用它们(当你不需要用它们修改容器),就更喜欢const iterator,以更好地logging你的阅读意图而不用修改。