2

I went through few of the answer about lambdas in C++ like: what is a lamba expression expression in C++ 11 The answers were quite helpful, however I am having difficulty to understand following the code.

I have a vector of ints

    std::vector <int> ivec{ 19,2,23,15 };

I want to sort it in descending order so

    sort(ivec.begin(), ivec.end(), [](auto x, auto y) {return(y < x); });

The parameters for lamdas parameter list is auto x and auto y

when the above line of code is being executed what is being passed in the parameter list as parameter?

IcanCode
  • 509
  • 3
  • 16
  • `auto` was added in the C++14 standard for *generic* [lambdas](https://en.cppreference.com/w/cpp/language/lambda). And as `auto` used for normal definitions the compiler will do automatic type deduction for the arguments. – Some programmer dude Jun 27 '21 at 14:00
  • As for what will be passed to the lambda function, it is the same as if you declared the arguments as `int x, int y`. – Some programmer dude Jun 27 '21 at 14:01
  • @Someprogrammerdude i am asking about the parameter's value not their type – IcanCode Jun 27 '21 at 14:01
  • Then no one can answer the question as it's implementation defined. The lambda will be called enough times to sort the container, but we can't say with what values or in what order, or even how many times the lambda will be called. If you want to know what values are passed for *your* implementation, then simply print them out. – Some programmer dude Jun 27 '21 at 14:02
  • @Someprogrammerdude then how did the sort function knew it has to sort in descending order – IcanCode Jun 27 '21 at 14:04
  • The `std::sort` function *doesn't* know. That's up to what the ordering function (your lambda) is doing. Your lambda uses less-than comparison, which will sort ascending order. Using greater-than will sort in descending order. – Some programmer dude Jun 27 '21 at 14:06
  • Also note that your use of `std::sort` is no different than the two-argument overload which defaults to using [`std::less`](https://en.cppreference.com/w/cpp/utility/functional/less). – Some programmer dude Jun 27 '21 at 14:15
  • 3
    @Someprogrammerdude in OPs lambda the arguments are reversed, so it's descending order – Caleth Jun 28 '21 at 10:34
  • @Caleth Oops, missed that. – Some programmer dude Jun 28 '21 at 11:03

1 Answers1

3

Lambda creation

I think I had the same confusion when I first saw lambdas.

So let's see what this expression means:

[](auto x, auto y) {return(y < x); }

This just creates the lambda object. It does not call the labda. Think of it as a class definition + object creation.

Your questions

Let's consider the declaration of sort:

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

and your call to it

sort(ivec.begin(), ivec.end(), [](auto x, auto y) { return(y < x); });

when the above line of code is being executed?

I'll interpret this as "when is the body of the lambda executed?"

Whenever sort calls it. What you need to understand: sort receives a parameter named comp that is callable. This parameter can be of type: pointer to function or a callable type (i.e. a type with operator() defined). A lambda is a special case of a callable type. When you call sort you just pass this object to the sort function. Now sort has an object (comp) that it can call whenever it wants/needs.

what is being passed in the parameter list as parameter?

Whatever sort passes as arguments when it calls comp. It the case of std::sort it will call it with pairs of elements from the range with the purpose of determining if those two elements are already sorted between them or not.

Example

The easiest is to just see it in action. For this lets consider the simplest sorting algorithm: a dumb bubble sort:

template< class RandomIt, class Compare >
void bubble_sort( RandomIt first, RandomIt last, Compare comp )
{
    for (auto left = first; left != last; ++left)
    {
        for (auto right = std::next(left); right != last; ++right)
        {
            if (!comp(*left, *right))
            {
                std::swap(*left, *right);
            }
        }
    }
}

the algorithm is for exposition only

As you can see bubble_sort makes calls to comp by passing arguments. Like std::sort the arguments passed are pairs of elements from the [first, last) range.

bolov
  • 72,283
  • 15
  • 145
  • 224