Is comparison of const_iterator with iterator well-defined?

前端 未结 3 995
清歌不尽
清歌不尽 2020-12-15 15:50

Consider the following code:

#include 
#include 

int main()
{
    std::vector vec{1,2,3,5};
    for(auto it=vec.cbe         


        
3条回答
  •  情歌与酒
    2020-12-15 16:36

    Table 96 in the C++11 Standard, in section 23.2.1, defines the operational semantics of a.cend() for any container type X (including std::vector) as follows:

    const_cast(a).end()
    

    So the answer is yes because by this definition cend() refers to the same element/position in the container as end(), and X::iterator must be convertible to X::const_iterator (a requirement also specified in the same table(*)).

    (The answer is also yes for begin() vs. cbegin() for the same reasons, as defined in the same table.)


    (*) It has been pointed out in comments to other answers that convertibility does not necessarily imply that the comparison operation i1==i2 will always work, e.g. if operator==() is a member function of the iterator type, the implicit conversion will only be accepted for the righthand-side argument, not the lefthand-side one. 24.2.5/6 states (about forward-iterators a and b):

    If a and b are both dereferenceable, then a == b if and only if *a and *b are bound to the same object

    Even though the iterators end() and cend() are not dereferenceable, the statement above implies that operator==() must be defined in such a way that the comparison is possible even if a is a const-iterator and b is not, and vice versa, because 24.2.5 is about forward-iterators in general, including both const- and non-const-versions -- this is clear e.g. from 24.2.5/1. This is why I am convinced that the wording from Table 96, which refers to convertibility, also implies comparability. But as described in cpplearner@'s later answer, this has been made explicitly clear only in C++14.

提交回复
热议问题