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::iterator
Return type: iterator type whose value type is
T
Note: any iterator category that meets the forward iterator requirements. convertible to
X::const_iterator
.
Expression:
X::const_iterator
Return type: constant iterator type whose value type is
T
Note: 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
X
satisfies the requirements of an input iterator for the value typeT
ifX
satisfies 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