std::max(3)
π NAME π
std::max β okay so it's literally just std::max, bestie. That's the whole name. It lives in the C++ Standard Library (like, the (3) up in the corner is the manual section, don't worry about it), and it does exactly one thing: it tells you which of your values is the bigger one. Iconic. No cap.
β¨ Synopsis β¨
It's defined in the header <algorithm> β write that down, you will forget it πΈ
template< class T > (1) (constexpr since C++14)
const T& max( const T& a, const T& b );
template< class T, class Compare > (2) (constexpr since C++14)
const T& max( const T& a, const T& b, Compare comp );
template< class T > (3) (since C++11)
T max( std::initializer_list<T> ilist ); (constexpr since C++14)
template< class T, class Compare > (4) (since C++11)
T max( std::initializer_list<T> ilist, Compare comp ); (constexpr since C++14)
So basically: returns the greater of the given values π«Ά
- 1, 2) Returns the greater of
aandb.- 1) Uses
operator<to compare the values. IfTis not LessThanComparable, the behavior is undefined π (like, don't, fr). - 2) Uses the comparison function
compto compare the values.
- 1) Uses
- 3, 4) Returns the greatest of the values in initializer list
ilist. Ifilist.size()is zero, orTis not CopyConstructible, the behavior is undefined π- 3) Uses
operator<to compare the values. IfTis not LessThanComparable, the behavior is undefined. - 4) Uses the comparison function
compto compare the values.
- 3) Uses
π Parameters π
a,bβ the values to compare πilistβ initializer list with the values to comparecompβ comparison function object (i.e. an object that satisfies the requirements of Compare) which returnstrueifais less thanb.
The signature of the comparison function should be equivalent to the following:
bool cmp(const Type1& a, const Type2& b);
Okay so about comp, and this part is lowkey a lot but it matters π: while the signature does not need to have const&, the function must not modify the objects passed to it, and it must be able to accept all values of type (possibly const) Type1 and Type2 regardless of value category (thus, Type1& is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11)). The types Type1 and Type2 must be such that an object of type T can be implicitly converted to both of them.
π Return value π
- 1, 2) The greater of
aandb. If they are equivalent, returnsa. (Tie goes toa, that's just the rules π) - 3, 4) The greatest value in
ilist. If several values are equivalent to the greatest, returns the leftmost one.
β Complexity β
Given N as ilist.size():
- 1) Exactly one comparison using
operator<. - 2) Exactly one application of the comparison function
comp. - 3) Exactly
N-1comparisons usingoperator<. - 4) Exactly
N-1applications of the comparison functioncomp.
Like, it is so efficient. It ate and left no crumbs π₯
π§ Possible implementation π§
max (1)
template<class T>
const T& max(const T& a, const T& b)
{
return (a < b) ? b : a;
}
max (2)
template<class T, class Compare>
const T& max(const T& a, const T& b, Compare comp)
{
return (comp(a, b)) ? b : a;
}
max (3)
template<class T>
T max(std::initializer_list<T> ilist)
{
return *std::max_element(ilist.begin(), ilist.end());
}
max (4)
template<class T, class Compare>
T max(std::initializer_list<T> ilist, Compare comp)
{
return *std::max_element(ilist.begin(), ilist.end(), comp);
}
π¦ Notes π¦
β οΈ Okay this is the important one, bestie: capturing the result of std::max by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned. Like:
int n = -1;
const int& r = std::max(n + 2, n * 2); // r is dangling
Not me warning you and you still doing it π Just don't hold a reference to a temporary. Periodt.
πΈ Example πΈ
// Run this code
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string_view>
int main()
{
auto longest = [](const std::string_view s1, const std::string_view s2)
{
return s1.size() < s2.size();
};
std::cout << "Larger of 69 and 96 is " << std::max(69, 96) << "\n"
"Larger of 'q' and 'p' is '" << std::max('q', 'p') << "'\n"
"Largest of 010, 10, 0X10, and 0B10 is "
<< std::max({010, 10, 0X10, 0B10}) << '\n'
<< R"(Longest of "long", "short", and "int" is )"
<< std::quoted(std::max({"long", "short", "int"}, longest)) << '\n';
}
Output
Larger of 69 and 96 is 96
Larger of 'q' and 'p' is 'q'
Largest of 010, 10, 0X10, and 0B10 is 16
Longest of "long", "short", and "int" is "short"
(Yes, 010 and 0X10 are octal and hex, that's why you get 16 β the vibe check passed π)
π Defect reports π
The following behavior-changing defect reports were applied retroactively to previously published C++ standards. (History being rewritten, main character energy π)
- DR
LWG 281, applied to C++98: behavior as published was thatTwas required to be CopyConstructible for overloads (1, 2) β correct behavior: not required. Slay, they fixed it β¨
π See also π
minβ returns the smaller of the given values (function template)minmax(C++11) β returns the smaller and larger of two elements (function template)max_elementβ returns the largest element in a range (function template)clamp(C++17) β clamps a value between a pair of boundary values (function template)ranges::max(C++20) β returns the greater of the given values (niebloid)
That's the whole page, bestie, go forth and compare things π β¨
Signing off with the source, the version and the date so you can cite me properly: this came from http://cppreference.com, version 2024.06.10, dated 2024.06.10 β manual page std::max(3), mwah π«Άπ
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms