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

时间:2008-11-21 17:36:25

标签: c++ stl iterator const

const_iteratoriterator之间有什么区别?你会在哪一方面使用另一个?

7 个答案:

答案 0 :(得分:100)

const_iterator s不允许您更改他们指向的值,常规iterator

与C ++中的所有内容一样,总是更喜欢const,除非有充分的理由使用常规迭代器(即您希望使用它们不是const来改变指向的事实 - 重视)。

答案 1 :(得分:34)

它们几乎应该是不言自明的。如果迭代器指向类型为T的元素,则const_iterator指向“const T”类型的元素。

它基本上等同于指针类型:

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元素的迭代器,因此迭代器本身可以更新(例如递增或递减),它指向的元素不能更改。

答案 2 :(得分:7)

不幸的是,STL容器的许多方法都使用迭代器而不是 const_iterators 作为参数。所以,如果你有一个 const_iterator ,你不能说“在这个迭代器指向的元素之前插入一个元素”(在我看来,这样的事情在概念上不是一个const违规)。如果你想要这样做,你必须使用 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())。因此,当您使用增强容器时,您可以“持久”。顺便说一下,有人知道STL容器是否或何时会被修复?

答案 3 :(得分:5)

尽可能使用 const_iterator ,在没有其他选择时使用迭代器

答案 4 :(得分:1)

最小例子

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

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,并根据容器变量的常量返回iteratorconst_iterator

弹出const_iterator的常见情况是在this方法中使用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迭代器,以便更好地记录你无意修改的意图。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

ok让我用非常简单的例子解释它,而不使用常量迭代器 考虑我们收集随机整数集合“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;

可以看出,在集合中使用正常的迭代器来编写/编辑数据,但是为了读取目的,使用了常量迭代器。如果您尝试在第一个for循环中使用常量迭代器,则会出现错误。作为一个拇指规则使用常量迭代器来读取集合中的数据。