Custom iterators and Iterator concepts

C++
Author

Quasar

Published

December 28, 2024

From skimming through named requirements and iterator concepts on cppreference.com, I infer that prior to C++20, things like InputIterator(now LegacyInputIterator), ForwardIterator(now LegacyForwardIterator) only existed as named requirements (as defined in the standard) and not baked in in the language. The burden to ensure that a type T satisfies a requirement R lies with the iterator writer/algorithm user. Also, I imagine, you can’t write a trait(type metafunction), for something like a, RandomAccessIterator which must support constant-time ++ and += operations.

So, pre- C++20 iterator concepts aren’t actually concepts in the sense of the C++20 language feature.

With C++20, these requirements have been formalized as C++ concepts. The older STL algorithm variants have been left untouched. For instance, if you look at std::find, an implementation would have the interface:

template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );

So, it doesn’t use concepts to constrain InputIt. The user of the legacy algorithms has to vouch for the passed types to satisfy the legacy requirements stated in the standard, otherwise the call will cause undefined behavior.

But, the newer ranges algorithms, for example, ranges::find constrain the arguments to satisfy various predicates.

template< std::input_iterator I, ...>,
constexpr I find(I first,...)