3rd paramater for min/max_element in <algorithms>

I dont understand what the 3rd paramater is for the min_element or max_element functions.

I've seen the reference on this website, as well as the example reproduced below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// min_element/max_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::min_element, std::max_element

bool myfn(int i, int j) { return i<j; }

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  // using default comparison:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';

  // using function myfn as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myfn) << '\n';

  // using object myobj as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myobj) << '\n';

  return 0;
}


I dont understand line 19, 20 and 23, 24.
What is the 3rd parameter 'myfn' and 'myobj' in those lines, and what role are these functions playing in finding the min or max element? They return bool so this isn't making sense to me.
Last edited on
Read this:

http://www.cplusplus.com/reference/algorithm/min_element/?kw=min_element

for the use of the third parameter.

min_element/max_element expects a function[like] object that requires two parameters and a bool value as the return value.

It is expected that the function object returns true when the left parameter is less than the right parameter.

Change the < to > on line 5 and/or 8 and see what happens.
Lets do the beginner's "find largest element":
1
2
3
4
5
6
7
auto max = arr[0];
for ( size_t i = 1; i < N; ++i ) {
  auto value = arr[i];
  if ( max < value ) {
    max = value;
  }
}

Focus on line 4. There is an expression max < value as condition. That expression dictates what is largest.

The operator< is a function. A binary predicate function. Binary = takes two operands; predicate = returns bool.

The operator syntax (operand operator operand) is convenient. but function syntax is also allowed:
operator< ( max, value )
If we are using a function in the expression, we could have used some other suitable function instead:
pred( max, value )
The 'pred' has to accept two arguments and return a bool.

In the example in your post there is 'myfn' that meets that criteria.
The global variable 'myobj' is of type myclass. myclass has operator() that allows myobj to be used like pred is used.

The possibility to replace the expression in the condition makes the three argument version of max_element much more generic. You can redefine what you mean by "larger".


Take class Person. It can have many attributes. For example age and height.
We can write operator< for class Person, but how should it compare two persons? When is one more than other?

What if we don't care about absolute "moreness" and want the tallest person? Or the youngest?
That is where the third parameter shines. We give min_element a pred that takes two persons and compares age.
Im still not understanding.

myfn is expecting two int parameters. But I dont see any arguments being passed on line 19 or 20?
The provided function object [myfn] is called within the body of min_element()/max_element() function and so the parameters are passed.
In the reference page for std::min_element there is a possible implementation of std::min_element. I'll copy it here:
1
2
3
4
5
6
7
8
9
10
11
12
template <class ForwardIterator, class Compare>
ForwardIterator
min_element ( ForwardIterator first, ForwardIterator last, Compare comp )
{
  if ( first == last ) return last;
  ForwardIterator smallest = first;

  while ( ++first != last )
    if ( comp(*first, *smallest) )    // Here is the call with two arguments
      smallest = first;
  return smallest;
}
Topic archived. No new replies allowed.