Why does ITER_CONCEPT befog iterator_traits::iterator_concept/category?
According to the [iterator.concepts.general]:
Otherwise, if iterator_traits names a specialization generated from the primary template, then ITER_CONCEPT(I) denotes random_access_iterator_tag.
ITER_CONCEPT(I) may be std::random_access_iterator_tag
,
even if I models input_iterator.
What is the purpose of this?
Why does c++ 20 iterator concept(such as std::forward_iterator
) still checks whether the ITER_CONCEPT is derived from a certain tag?
Example:
template<class I>
concept forward_iterator =
input_iterator<I> &&
derived_from<ITER_CONCEPT(I), forward_iterator_tag> && //is this necessary?
incrementable<I> &&
sentinel_for<I, I>;
To be an X iterator, the iterator concept requires (among other things) two things. It is possible for a type to accidentally fulfill an iterator's syntactic requirements without intending to. As such, to be an X iterator, the prospective iterator type must declare that it intends to be (at least) an X iterator. This is done through the tag
type, as retrieved through ITER_CONCEPT
.
But iterators have an "inheritance" graph of sorts. All random access iterators are also bidirectional. So each iterator concept requires that the prospective iterator type fulfill the concept requirements of its "base" iterator concept.
These are separate requirements. Types can lie, after all, and the whole point of concepts is to keep types from lying. Just because a type claims to be a forward iterator does not mean it actually is one.
As for the purpose of this particular rule in ITER_CONCEPT
, it is to bypass the defaulting mechanism defined for the legacy iterator_category
. The idea is that if you haven't specified your iterator's tag type explicitly, then ITER_CONCEPT
will assume the (second) most permissive one and then use C++20's concept checks to see what your iterator actually supports.
It doesn't mean that this iterator is definitely a random access iterator; it's saying "try (almost) anything, and if the concept doesn't fit, then that isn't it".