I have two iterators into a container, one const and one non-const. Is there an issue with comparing them to see if they both refer to the same object in the container? This is a general C++11 iterator question:
Can a const and non-const iterator be legitimately compared to see if they both refer to the same object, independent of the type of container (i.e., they are both iterators that are guaranteed to refer to objects in the same container or that container's end(), but one is const and the other is not)?
For example, consider the following code:
some_c++11_container container;
// Populate container
...
some_c++11_container::iterator iObject1=container.begin();
some_c++11_container::const_iterator ciObject2=container.cbegin();
// Some operations that move iObject1 and ciObject2 around the container
...
if (ciObject2==iObject1) // Is this comparison allowed by the C++11 standard?
...; //Perform some action contingent on the equality of the two iterators
Yes, this will work like you expect.
The Standard guarantees that for any container type, some_container::iterator can be implicitly converted to some_container::const_iterator.
The first table in 23.2.1 [container.requirements.general], after defining X as a container type which contains objects of type T, has:
Expression:
X::iteratorReturn type: iterator type whose value type is
TNote: any iterator category that meets the forward iterator requirements. convertible to
X::const_iterator.
Expression:
X::const_iteratorReturn type: constant iterator type whose value type is
TNote: any iterator category that meets the forward iterator requirements.
(These aren't really expressions, and are types, rather than having "return types", but that's how they're squeezed into the table that is mostly expressions.)
So when you have ciObject2==iObject1, the compiler notices that the best operator== is ciObject2==some_container::const_iterator(iObject1). And operator== on two const_iterator tells you if they refer to the same element.
(I don't see anything explicitly saying that the result of this conversion refers to the same object as the original iterator. I guess that's just understood.)
From §24.2.3/1
A class or pointer type
Xsatisfies the requirements of an input iterator for the value typeTifXsatisfies theIterator(24.2.2) andEqualityComparable(Table 17) requirements ...
Thus input iterators are required to be EqualityComparable.
All standard library container iterators must satisfy forward iterator requirements (§23.2.1 - Table 96). Since those requirements are a superset of input iterator requirements, it follows these iterators must satisfy the EqualityComparable concept.
Also, from §23.2.1 - Table 96, X::iterator is required to be convertible to
X::const_iterator.
Adding the two together answers your question that it is indeed required by the standard that comparing a Container::const_iterator to a Container::iterator is well-defined (as long as both are valid iterators pointing to the same container).
I don't think it is possible for there to be an issue comparing them. If you have a const iterator when you check for it being the end the iterator end() returns is not const.
IIRC iterator implicitly converts to const_iterator. And the result must point to the same position.
If so the mixed compare will do the conversion then compare the now compatible const_iterators.
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