Sad egg
Sad egg

Reputation: 99

In C++, is "const_iterator" the same as "const iterator"?

Is a const_iterator the same as const iterator? if not what's the difference? if yes why does standard use const_iterator when const iterator is already meaningful?

For example, are these two declarations exactly the same ?

string& replace (const_iterator i1, const_iterator i2, const string& str);

string& replace (const iterator i1, const iterator i2, const string& str);

Upvotes: 4

Views: 1909

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117258

No, they are not the same.

Like any const object, you can not make changes to a const iterator:

// ++it gives error below since we try to change it:
for(const std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {}

You are, however, allowed to change the value of the object a const iterator is pointing at:

// this is ok (assuming there is at least one element in the vector):
const std::vector<int>::iterator it = vec.begin();
*it = 10;

A const_iterator is mutable, but you can not change the object that the iterator is pointing at:

// ++it is ok below:
for(std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it) {
    *it = 10;   // error:  `*it`  is an `int const&`
}

With a const const_iterator, you can neither make changes to the iterator nor what it is pointing at.

const std::vector<int>::const_iterator it = vec.begin();
++it;                     // error
*it = 10;                 // error
std::cout << *it << '\n'; // ok

A constructed example to illustrate:

struct foo {
    using const_iterator = char const*;
    using iterator = char*;

    const_iterator cbegin() const { return data; };
    const_iterator cend() const { return data + sizeof data; };
    const_iterator begin() const { return cbegin(); }
    const_iterator end() const { return cend(); }
    iterator begin() { return data; };
    iterator end() { return data + sizeof data; };

    char data[2];
};

As seen above, const_iterator and iterator are user defined type definitions. Only by convention are the names called what they are called. Using these conventional names also helpes when creating containers that are supposed to work well with other classes, since these type definitions are often used to create or specify instances/types. The names const_iterator and iterator do not give these alias any special properties though. It's all up to the creator of the class.

Upvotes: 8

Related Questions