Online Book Reader

Home Category

Professional C__ - Marc Gregoire [195]

By Root 1522 0
"hello");

for (auto& str : stringVector) {

str.append(" there");

}

Code snippet from VectorIterators\AccessingFields.cpp

const_iterator

The normal iterator is read/write. However, if you call begin() and end() on a const object, you receive a const_iterator. The const_iterator is read-only; you cannot modify the elements. An iterator can always be converted to a const_iterator, so it’s always safe to write something like this:

vector::const_iterator it = myVector.begin();

However, a const_iterator cannot be converted to an iterator. If myVector is const, the following line doesn’t compile:

vector::iterator it = myVector.begin();

If you do not need to modify the elements of a vector, you should use a const_iterator. This rule will make it easier to guarantee correctness of your code and allows compilers to perform certain optimizations.

When using the auto keyword of C++11, using const_iterators looks a bit different. Suppose you write the following code:

vector stringVector(10, "hello");

for (auto iter = stringVector.begin();

iter != stringVector.end(); ++iter) {

cout << *iter << endl;

}

Because of the auto keyword, the compiler will decide the type of the iter variable automatically and will make it a normal iterator, meaning that you can read and write to the iterator. If you want a read-only const_iterator in combination with using auto, then you need to use cbegin() and cend() instead of the normal begin() and end() as follows:

vector stringVector(10, "hello");

for (auto iter = stringVector.cbegin();

iter != stringVector.cend(); ++iter) {

cout << *iter << endl;

}

Code snippet from VectorIterators\ConstIterator.cpp

Now the compiler will use the const_iterator as type for the variable iter because that’s what cbegin() returns.

Iterator Safety

Generally, iterators are about as safe as pointers: extremely insecure. For example, you can write code like this:

vector intVector;

auto it = intVector.end();

*it = 10; // BUG! it doesn't refer to a valid element.

Code snippet from VectorIterators\IteratorSafety.cpp

Recall that the iterator returned by end() is past the end of the vector. Trying to dereference it results in undefined behavior. However, the iterators themselves are not required to perform any verification.

Remember that end() returns an iterator past the end of the container, not the iterator referring to the last element of the container.

Another problem can occur if you use mismatched iterators. For example, the following code initializes an iterator from vectorTwo and tries to compare it to the end iterator for vectorOne. Needless to say, this loop will not do what you intended, and may never terminate. Dereferencing the iterator in the loop will likely produce undefined results.

vector vectorOne(10);

vector vectorTwo(10);

// Fill in the vectors.

// BUG! Infinite loop

for (auto it = vectorTwo.begin(); it != vectorOne.end(); ++it) {

// Loop body

}

Code snippet from VectorIterators\IteratorSafety.cpp

Some C++ runtimes, for example Microsoft Visual C++, will give an assertion error at run time for both of the preceding problems when running a debug build of your program.

Other Iterator Operations

The vector iterator is random access, which means that you can move it backward or forward, or jump around. For example, the following code eventually changes the fifth element (index 4) in the vector to the value 4:

vector intVector(10, 0);

auto it = intVector.begin();

it += 5;

--it;

*it = 4;

Code snippet from VectorIterators\IteratorOps.cpp

Iterators versus Indexing

Given that you can write a for loop that uses a simple index variable and the size() method to iterate over the elements of the vector, why should you bother using iterators? That’s a valid question, for which there are three main answers:

Iterators allow you to insert and delete elements and sequences of elements at any point in the container. See the following “Adding and Removing Elements” section.

Iterators allow you to use the STL

Return Main Page Previous Page Next Page

®Online Book Reader