简体   繁体   中英

Why does lambda function used for stl functions such as sort() , max_element() function in C++ take two arguments as input?

I am trying to understand the use of lambda function in sort() operator. There is a vector which stores object of type person ; sort() function is being used to iterate over the vector person and sort it based on class member id .

I do not understand why the lambda function used in the sort function needs two inputs ie. p1 and p2 ?, why not just input one object p1 ? I always thought stl functions such as sort() and max_element() return iterator to one element.

class Person
    {
      private:
        string firstName;
        string lastName;
        int id;

      public:
        Person(const string& fn, const string& ln, int i)
             : firstName(fn), lastName(ln), id(i) { }

        const string& getFirstName() const { return firstName; }
        const string& getLastName() const { return lastName; }
        int getID() const { return id; }
    };

main(){
vector<Person> people;
people.push_back(Person("Davor", "Loayza", 62341));
people.push_back(Person("Eva", "Lopez", 12345));
people.push_back(Person("Julio", "Sanchez", 54321));
people.push_back(Person("Adan", "Ramones", 70000));

sort(people.begin(), people.end(), [](const Person& p1, const Person& p2)
{
  return p1.getID() < p2.getID();
});
return 0;
}

Edit: may be I need to restate my question, my question was how does iterator increment occur in sort() function. At the very beginning when iterator = people.begin(), what value is assigned to p1 and what value is assigned to p2 ? Similarly what happens when iterator= people.end()? I am having hard time understanding the logic behind this process?

To understand std::sort , you must first understand what sorting is. Here's an exercise for you:

Find yourself a deck of cards. I'm going to assume that you know which card has a higher rank compared than another card; otherwise this may be confusing. It won't mater whether ace is higher rank than king, or lower than two. You can ignore suit for now.

Lay the cards in a row (or a fan to save space). The target is to find out whether any card with higher rank is before a card with lower rank. Think about how you could find that out?

This is how: Start with the first, and the second card. Compare their rank. Does the first card have higher rank than the second? If so, we conclude that the answer that we seek is "Yes, there is a card with a higher rank that is before a card of lower rank". If the first card doesn't have a higher rank than the second, then we cannot answer the question yet. We must move on and compare the second card with the third, and repeat the process.

If you reach the end of the deck without finding a card of higher rank that is before a card of lower rank, then the answer we seek is "No". Let us call such deck sorted (or ordered).

Second exercise: If the deck isn't sorted, how could you make it sorted?

This is how: Just like in first exercise, start with the first two cards. This time, if they aren't in the desired order, swap their position so that fist becomes second and second become first. Now the two cards are sorted in relation to each other. Then move on to the second and third and repeat the process. You'll find that you may need to repeat this process multiple times as one iteration is not necessarily sufficient.

Let us call this process sorting (more specifically, this is comparison sorting). This is what std::sort does. It compares two elements at a time, and swaps elements until all comparisons between any adjacent pair is true ie until the range is sorted.

The comparison that you did between two cards is analogous with the comparison step that is done by the comparison function object argument of std::sort . If you only looked at one card at a time, you wouldn't be able to find out whether it is in its ordered position or not.


Why does lambda function used for stl functions such as sort() , max_element() function in C++ take two arguments as input?

Because the comparison function object argument of those functions represents an order relation between two elements of an iterator range. Order relations are binary relations.

why not just input one object p1?

Because a unary relation cannot represent an order.

I always thought stl functions such as sort() and max_element() return iterator to one element.

how many iterators does sort() function return?

std::sort returns void as per documentation. That said, what these functions return, has little relevance with the arity of the comparison function object argument.

my question was how does iterator increment occur in sort() function

This is not specified. The implementer of the algorithm may choose how to increment the iterator. Sorting algorithms often use more than one iterator.

At the very beginning when iterator = people.begin() , what value is assigned to p1 and what value is assigned to p2 ?

A sorting algorithm doesn't have to start at the beginning of the range. It is unclear what you're referring to with iterator .

p1 and p2 will be some pair elements in the range of [first, last) . Exactly which pair is up for the algorithm to decide.

The lambda function is called on elements in the container, to compare if one is greater than the other. It's not just simply called once for the return of sort : sort returns nothing. It takes two parameters so it can compare. If it only took a single parameter, what would it compare it to?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM