Namespaces
Variants

std::ranges::max

From cppreference.com
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Non-modifying sequence operations    
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
(C++11)    

Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations


 
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Fold operations (Helper templates)
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
       
       
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
       
       
Permutation operations
Specialized <memory> algorithms
Return types
 
Defined in header <algorithm>
Call signature
template< class T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <std::projected<const T*, Proj>> Comp = ranges::less >
constexpr const T&
    max( const T& a, const T& b, Comp comp = {}, Proj proj = {} );
(1) (since C++20)
template< std::copyable T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <std::projected<const T*, Proj>> Comp = ranges::less >
constexpr T
    max( std::initializer_list<T> r, Comp comp = {}, Proj proj = {} );
(2) (since C++20)
template< ranges::input_range R, class Proj = std::identity,
          std::indirect_strict_weak_order
              <std::projected<ranges::iterator_t<R>,
                              Proj>> Comp = ranges::less >
    requires std::indirectly_copyable_storable<ranges::iterator_t<R>,
                                               ranges::range_value_t<R>*>
constexpr ranges::range_value_t<R>
    max( R&& r, Comp comp = {}, Proj proj = {} );
(3) (since C++20)
template< /*execution-policy*/ Ep, /*sized-random-access-range*/ R,
          class Proj = std::identity,
          std::indirect_strict_weak_order
              <std::projected<ranges::iterator_t<R>,
                              Proj>> Comp = ranges::less >
    requires std::indirectly_copyable_storable<ranges::iterator_t<R>,
                                               ranges::range_value_t<R>*>
ranges::range_value_t<R>
    max( Ep&& policy, R&& r, Comp comp = {}, Proj proj = {} );
(4) (since C++26)

For the definition of /*execution-policy*/, see this page; for the definition of /*sized-random-access-range*/, see this page.

Returns the greater of the given values (projected by proj), the projected values are compared using comp.

1) Returns the greater of a and b.
2-4) Returns the first greatest value in the initializer list or target range r.
If ranges::distance(r) is zero, the behavior is undefined.
4) Same as (3), but executed according to policy.

The function-like entities described on this page are algorithm function objects (informally known as niebloids), that is:

Parameters

a, b - the values to compare
r - the range of values to compare
comp - the comparator to be applied to the (projected) elements
proj - the projection to be applied to the elements
policy - the execution policy to use

Return value

1) The greater of a and b, according to their respective projected values. If they are equivalent, returns a.
2-4) The greatest value in r, according to the projection. If there are multiple greatest values, returns the first one of them.

Complexity

1) Exactly one application of comp, and two applications of proj.
2-4) Given N as ranges::distance(r):
2,3) Exactly N-1 applications of comp, and twice as many applications of proj.
4) 𝓞(N) applications of comp, and twice as many applications of proj.

Exceptions

4) During the execution process:
  • If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
  • If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).

Notes

Capturing the result of std::ranges::max by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned:

int n = -1;
const int& r = std::ranges::max(n + 2, n * 2); // r is dangling

Possible implementation

struct max_fn
{
    template<class T, class Proj = std::identity,
             std::indirect_strict_weak_order
                 <std::projected<const T*, Proj>> Comp = ranges::less>
    constexpr const T& operator()(const T& a, const T& b,
                                  Comp comp = {}, Proj proj = {}) const
    {
        return std::invoke(comp, std::invoke(proj, a), std::invoke(proj, b)) ? b : a;
    }
    
    template<std::copyable T, class Proj = std::identity,
             std::indirect_strict_weak_order
                 <std::projected<const T*, Proj>> Comp = ranges::less>
    constexpr T operator()(std::initializer_list<T> r,
                           Comp comp = {}, Proj proj = {}) const
    {
        return *ranges::max_element(r, std::ref(comp), std::ref(proj));
    }
    
    template<ranges::input_range R, class Proj = std::identity,
             std::indirect_strict_weak_order
                 <std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less>
        requires std::indirectly_copyable_storable<ranges::iterator_t<R>,
                                                   ranges::range_value_t<R>*>
    constexpr ranges::range_value_t<R> operator()(R&& r, Comp comp = {},
                                                  Proj proj = {}) const
    {
        using V = ranges::range_value_t<R>;
        if constexpr (ranges::forward_range<R>)
            return static_cast<V>(*ranges::max_element(r, std::ref(comp),
                                                       std::ref(proj)));
        else
        {
            auto i = ranges::begin(r);
            auto s = ranges::end(r);
            V m(*i);
            while (++i != s)
                if (std::invoke(comp, std::invoke(proj, m), std::invoke(proj, *i)))
                    m = *i;
            return m;
        }
    }
};

inline constexpr max_fn max;

Example

#include <algorithm>
#include <iostream>
#include <string>

static_assert(std::ranges::max({0B10, 0X10, 010, 10}) == 16); // overload (2)

int main()
{
    namespace ranges = std::ranges;
    using namespace std::string_view_literals;
    
    std::cout << "Larger of 1 and 9999: " << ranges::max(1, 9999) << '\n'
              << "Larger of 'a' and 'b': '" << ranges::max('a', 'b') << "'\n"
              << R"(Longest of "foo", "bar", and "hello": )"
              << ranges::max({"foo"sv, "bar"sv, "hello"sv}, {},
                             &std::string_view::size) << "\"\n";
}

Output:

Larger of 1 and 9999: 9999
Larger of 'a' and 'b': 'b'
Longest of "foo", "bar", and "hello": "hello"

See also

returns the greater of the given values
(function template) [edit]
returns the smaller of the given values
(algorithm function object)[edit]
returns the smaller and larger of two elements
(algorithm function object)[edit]
returns the largest element in a range
(algorithm function object)[edit]
clamps a value between a pair of boundary values
(algorithm function object)[edit]