3180. Inconsistently named return type for ranges::minmax_element

Section: 26.4 [algorithm.syn] Status: C++20 Submitter: Casey Carter Opened: 2018-12-21 Last modified: 2021-02-25

Priority: 0

View all other issues in [algorithm.syn].

View all issues with C++20 status.

Discussion:

The overloads of std::ranges::minmax_element are specified to return std::ranges::minmax_result, which is inconsistent with the intended design. When an algorithm foo returns an aggregate of multiple results, the return type should be named foo_result. The spec should introduce an alias minmax_element_result for minmax_result and use that alias as the return type of the std::ranges::minmax_element overloads.

[2019-01-11 Status to Tentatively Ready after five positive votes on the reflector.]

During that reflector discussion several contributers questioned the choice of alias templates to denote algorithm result types or particular aspects of it. Since this approach had been approved by LEWG before, it was suggested to those opponents to instead write a paper, because changing this as part of this issue would be a design change that would require a more global fixing approach.

Proposed resolution:

This wording is relative to N4791.

  1. Change 26.4 [algorithm.syn] as indicated, and adjust the declarations of std::ranges::minmax_element in 26.8.9 [alg.min.max] to agree:

    […]
    template<class ExecutionPolicy, class ForwardIterator, class Compare>
      pair<ForwardIterator, ForwardIterator>
        minmax_element(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads]
                       ForwardIterator first, ForwardIterator last, Compare comp);
    
    namespace ranges {
      template<class I>
      using minmax_element_result = minmax_result<I>;
    
      template<ForwardIterator I, Sentinel<I> S, class Proj = identity,
               IndirectStrictWeakOrder<projected<I, Proj>> Comp = ranges::less<>>
        constexpr minmax_element_result<I>
          minmax_element(I first, S last, Comp comp = {}, Proj proj = {});
      template<ForwardRange R, class Proj = identity,
               IndirectStrictWeakOrder<projected<iterator_t<R>, Proj>> Comp = ranges::less<>>
        constexpr minmax_element_result<safe_iterator_t<R>>
          minmax_element(R&& r, Comp comp = {}, Proj proj = {});
    }
    
    // 26.8.10 [alg.clamp], bounded value
    […]