5

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 require equality_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?

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • I wanted to vote to reopen my question, but I was able to single-handedly reopen it. :/ – HolyBlackCat Sep 24 '21 at 17:45
  • Not sure if [Difference between Ranges algorithms and std algorithms](https://stackoverflow.com/q/63867796/2752075) is the right dupe. It doesn't explicitly say if the requirements for the old algorithms were relaxed or left as is. – HolyBlackCat Sep 24 '21 at 17:46
  • I don't understand what you're asking. Are you asking what the algorithm requirements *are*? The phrasing of "I should use" is confusing - should use in what sense? – Barry Sep 24 '21 at 18:05
  • @Barry Edited, it should be better now. I'm asking if the old standard algorithms (non-`std::ranges` ones) still use the old (stricter) iterator requirements, or if the requirements for them were relaxed to match the concepts. – HolyBlackCat Sep 24 '21 at 18:11

1 Answers1

3

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 concepts (note that it would not change the std:: algorithms to accept sentinels).

Barry
  • 286,269
  • 29
  • 621
  • 977