Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is comparison of const_iterator with iterator well-defined?

Consider the following code:

#include <vector> #include <iostream>  int main() {     std::vector<int> vec{1,2,3,5};     for(auto it=vec.cbegin();it!=vec.cend();++it)     {         std::cout << *it;         // A typo: end instead of cend         if(next(it)!=vec.end()) std::cout << ",";     }     std::cout << "\n"; } 

Here I've introduced a typo: in the comparison I called vec.end() instead of vec.cend(). This appears to work as intended with gcc 5.2. But is it actually well-defined according to the Standard? Can iterator and const_iterator be safely compared?

like image 984
Ruslan Avatar asked Feb 14 '16 10:02

Ruslan


People also ask

What is the difference between iterator and Const_iterator?

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.

Can we compare iterators?

we can use == and != to compare to valid iterators into any of the library containers. The section also tells us that iterators for string and vector support relational operators (aka iterator arithmetic) which include >, >=, <, <=.

How do you compare iterator values?

To compare the values that two iterators are pointing at, dereference the iterators first, and then use a comparison operator. Operator= -- Assign the iterator to a new position (typically the start or end of the container's elements).

Should iterators be passed by value or reference?

In general: If you pass a non- const reference, the caller doesn't know if the iterator is being modified. You could pass a const reference, but usually iterators are small enough that it gives no advantage over passing by value.


2 Answers

Surprisingly, C++98 and C++11 didn't say that you can compare a iterator with a const_iterator. This leads to LWG issue 179 and LWG issue 2263. Now in C++14, this is explicitly permitted by § 23.2.1[container.requirements.general]p7

In the expressions

i == j i != j i < j i <= j i >= j i > j i - j 

where i and j denote objects of a container's iterator type, either or both may be replaced by an object of the container's const_iterator type referring to the same element with no change in semantics.

like image 174
cpplearner Avatar answered Sep 23 '22 02:09

cpplearner


See §23.2.1, Table 96:

X::iterator 

[...]

any iterator category that meets the forward iterator requirements.

convertible to X::const_iterator

So, yes, it is well-defined.

like image 42
Christian Hackl Avatar answered Sep 25 '22 02:09

Christian Hackl