In C 20 we got concepts for iterator categories, e.g. std::forward_iterator
corresponds to named requirement ForwardIterator.
They are not equivalent. In some (but not all) regards, the concepts are weaker:
(1) "Unlike the [ForwardIterator or stricter] requirements, the [corresponding] concept does not require dereference to return an lvalue."
(2) "Unlike the [InputIterator] requirements, the
input_iterator
concept does not requireequality_comparable
, since input iterators are typically compared with sentinels."...
The new std::ranges
algorithms seem to use the concepts to check iterator requirements.
But what about the other standard algorithms? (that existed pre-C 20)
Do they still use the same iterator requirements in C 20 as they were pre-C 20, or did the requirements for them get relaxed to match the concepts?
CodePudding user response:
Do they still use the same iterator requirements in C 20 as they were pre-C 20, or did the requirements for them get relaxed to match the concepts?
The existing std::
algorithms still use the named requirements. For instance, [alg.find] has both:
template<class InputIterator, class T>
constexpr InputIterator find(InputIterator first, InputIterator last,
const T& value);
and
template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
constexpr I ranges::find(I first, S last, const T& value, Proj proj = {});
template<input_range R, class T, class Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
constexpr borrowed_iterator_t<R>
ranges::find(R&& r, const T& value, Proj proj = {});
The same is true for all the algorithms.
Note that there is a proposal to change this: Ranges views as inputs to non-Ranges algorithms. That paper would change the named requirements to become in line with the concept
s (note that it would not change the std::
algorithms to accept sentinels).