Someone here recently brought up the article from Scott Meyers that says:
iterators
over const_iterators
(pdf link).Someone else was commenting that the article is probably outdated. I'm wondering what your opinions are?
Here is mine: One of the main points of the article is that you cannot erase or insert on a const_iterator
, but I think it's funny to use that as an argument against const_iterators
. I thought the whole point of const_iterators
it that you do not modify the range at all, neither the elements themselves by substituting their values nor the range by inserting or erasing. Or am I missing something?
The primary purpose of an iterator is to allow a user to process every element of a container while isolating the user from the internal structure of the container. This allows the container to store elements in any manner it wishes while allowing the user to treat it as if it were a simple sequence or list.
There is no performance difference. A const_iterator is an iterator that points to const value (like a const T* pointer); dereferencing it returns a reference to a constant value ( const T& ) and prevents modification of the referenced value: it enforces const -correctness.
An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.
An iterator can either be a constant or a non-constant/regular iterator.
I totally agree with you. I think the answer is simple: Use const_iterators where const values are the right thing to use, and vice versa. Seems to me that those who are against const_iterators must be against const in general...
Here's a slightly different way to look at it. Const_iterator
almost never makes sense when you are passing it as a pointer into a specific collection and you are passing the collection as well. Mr. Meyer was specifically stating that const_iterator
cannot be used with most member functions of a collection instance. In that case, you will need a plain-old iterator
. However, if you don't have a handle to the collection, the only difference between the two is that you can modify what is pointed to by an iterator
and you can't modify the object referenced by a const_iterator
.
So... you want to use iterator
whenever you are passing a collection and position into the collection to an algorithm. Basically, signatures like:
void some_operation(std::vector<int>& vec, std::vector::const_iterator pos);
don't make a whole lot of sense. The implicit statement is that some_operation
is free to modify the underlying collection but is not allowed to modify what pos
references. That doesn't make much sense. If you really want this, then pos
should be an offset instead of an iterator.
On the flip side, most of the algorithms in the STL are based on ranges specified by a pair of iterators. The collection itself is never passed so the difference between iterator
and const_iterator
is whether the value in the collection can be modified through the iterator or not. Without a reference to the collection, the separation is pretty clear.
Hopefully that made things as clear as mud ;)
I don't think this particular statement of Meyer's needs to be taken with special concern. When you want a non-modifying operation, it is best to use a const_iterator
. Otherwise, use an ordinary iterator
. However, do note the one important thing: Never mix iterators i.e. const
ones with non-const
ones. As long as you are aware of the latter, you should be fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With