std::min(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

std::min πŸ’… (the C++ Standard Library page, bestie)

okay so first of all, this is std::min from the C++ Standard Library, and she is literally the most iconic little function in <algorithm>. like yes she picks the smaller one. that's her job. that's her whole personality and she ATE. ✨


✨ Synopsis ✨

she lives here, no cap:

Defined in header <algorithm>

template< class T >                                    (1) (constexpr since C++14)
const T& min( const T& a, const T& b );

template< class T, class Compare >                     (2) (constexpr since C++14)
const T& min( const T& a, const T& b, Compare comp );

template< class T >                                    (3) (since C++11)
T min( std::initializer_list<T> ilist );                   (constexpr since C++14)

template< class T, class Compare >                     (4) (since C++11)
T min( std::initializer_list<T> ilist, Compare comp );     (constexpr since C++14)

so what does she do? returns the smaller of the given values. that's it. that's the tweet. 🫢

  • 1,2) β€” returns the smaller of a and b.
    • 1) β€” uses operator< to compare the values. if T is not LessThanComparable, the behavior is undefined 😭 (like, go touch grass, undefined behavior is not the vibe).
    • 2) β€” uses the comparison function comp to compare the values.
  • 3,4) β€” returns the smallest of the values in initializer list ilist. if ilist.size() is zero, or T is not CopyConstructible, the behavior is undefined πŸ’€.
    • 3) β€” uses operator< to compare the values. if T is not LessThanComparable, the behavior is undefined.
    • 4) β€” uses the comparison function comp to compare the values.

🌸 Parameters 🌸

  • a, b β€” the values to compare πŸ‘―β€β™€οΈ
  • ilist β€” initializer list with the values to compare
  • comp β€” comparison function object (i.e. an object that satisfies the requirements of Compare) which returns true if a is less than b.

the signature of the comparison function should be equivalent to the following:

bool cmp(const Type1& a, const Type2& b);

okay so listen, this part is kind of 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 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)). 🧚

and the types Type1 and Type2 must be such that an object of type T can be implicitly converted to both of them. iykyk. ✨


πŸŽ€ Return value πŸŽ€

  • 1,2) β€” the smaller of a and b. if the values are equivalent, returns a. (she's loyal to the left, periodt.)
  • 3,4) β€” the smallest value in ilist. if several values are equivalent to the smallest, returns the leftmost such value. queen of consistency πŸ‘‘

πŸ¦‹ Complexity πŸ¦‹

  • 1) β€” exactly one comparison using operator<.
  • 2) β€” exactly one application of the comparison function comp.
  • 3,4) β€” given (\scriptsize N)N as ilist.size():
    • 3) β€” exactly (\scriptsize N-1)N-1 comparisons using operator<.
    • 4) β€” exactly (\scriptsize N-1)N-1 applications of the comparison function comp.

not her doing extra work for no reason, she's efficient πŸ’…


πŸ’œ Possible implementation πŸ’œ

here's how she'd look if you wrote her yourself, lowkey:

min (1)

template<class T>
const T& min(const T& a, const T& b)
{
    return (b < a) ? b : a;
}

min (2)

template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp)
{
    return (comp(b, a)) ? b : a;
}

min (3)

template<class T>
T min(std::initializer_list<T> ilist)
{
    return *std::min_element(ilist.begin(), ilist.end());
}

min (4)

template<class T, class Compare>
T min(std::initializer_list<T> ilist, Compare comp)
{
    return *std::min_element(ilist.begin(), ilist.end(), comp);
}

⚠️ Notes ⚠️

bestie. listen to me. capturing the result of std::min by reference produces a dangling reference if one of the parameters is a temporary and that parameter is returned. 🚨 this is the part where you don't get to be cute.
int n = -1;
const int& r = std::min(n + 2, n * 2); // r is dangling

like... r is hanging on by a thread and there is no thread. 😭


🌈 Example 🌈

// Run this code

#include <algorithm>
#include <iostream>
#include <string_view>

int main()
{
    std::cout << "smaller of 10 and 010 is " << std::min(10, 010) << '\n'
              << "smaller of 'd' and 'b' is '" << std::min('d', 'b') << "'\n"
              << "shortest of \"foo\", \"bar\", and \"hello\" is \""
              << std::min({"foo", "bar", "hello"},
                          [](const std::string_view s1, const std::string_view s2)
                          {
                              return s1.size() < s2.size();
                          }) << "\"\n";
}

Output:

smaller of 10 and 010 is 8
smaller of 'd' and 'b' is 'b'
shortest of "foo", "bar", and "hello" is "foo"

(and yes, 010 is octal, that's why it's 8, don't come for me, that's just the example doing its thing πŸ“)


🫢 Defect reports 🫢

the following behavior-changing defect reports were applied retroactively to previously published C++ standards. history said what it said and then got corrected, we love growth πŸ’…

  • LWG 281 β€” applied to C++98. behavior as published: T was required to be CopyConstructible for overloads (1,2). correct behavior: not required. slay for fixing that ✨

πŸ‘‘ See also πŸ‘‘

  • max β€” returns the greater of the given values (function template)
  • minmax β€” returns the smaller and larger of two elements (C++11) (function template)
  • min_element β€” returns the smallest element in a range (function template)
  • clamp β€” clamps a value between a pair of boundary values (C++17) (function template)
  • ranges::min β€” returns the smaller of the given values (C++20) (niebloid)

that's the whole page bestie, go pick the smaller one with confidence πŸ’–

source + version + date sign-off: straight from http://cppreference.com, version 2024.06.10, and this page is dated 2024.06.10 β€” std::min(3), mwah. πŸŽ€β­

πŸ“¦ where this page comes from