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".