sort result is not what I thought

sort can enter lambda function to the 3rd parameter, but I don't know why
below function will sort different than what I thought

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream> 
#include <functional>
#include <algorithm>
using namespace std; 

int main() { 
    int number[] = {3, 5, 1, 6, 9};
    auto print = [](int n) { cout << n << " "; };

    sort(begin(number), end(number), [](int n1, int n2) { return n2 - n1; });
    // show 9 6 1 5 3
    for_each(begin(number), end(number), print);
    cout << endl;

    return 0; 
} 


I thought sorting result is like this:
1: 3 5 1 6 9
2: 5 3 1 6 9
3: 5 3 1 6 9
4: 6 5 3 1 9
5: 9 6 5 3 1 <-- Final sorting result

But why it shows 9 6 1 5 3 finally.
Last edited on
Do you expect five different lines to be printed?

It appears that you're only printing the array once.

No, I expect it shows 9 6 5 3 1 after sorting.
But I dont know how it sorts
The function passed to sort should use "less than" logic (bool, n1 < n2), not "comp" logic (negative, 0, positive). So if you want it sorted in reverse you should use return n1 > n2.
Last edited on
If it follows n1 < n2
Why it sort doesnt like what I wrote above?
I swap them if right integer bigger than left integer.

1: 3 5 1 6 9
2: 5 3 1 6 9 // swap 3 & 5
3: 5 3 1 6 9
4: 6 5 3 1 9 // swap 6 to first
5: 9 6 5 3 1 <-- Final sorting result
Because what you wrote above is not a boolean expression that returns true if the first argument is ordered before the second arguement.

https://en.cppreference.com/w/cpp/algorithm/sort
comp - comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than (i.e. is ordered before) the second.
The signature of the comparison function should be equivalent to the following:

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


What you wrote above is equivalent to:
sort(begin(number), end(number), [](int n1, int n2) { return (n2 - n1) != 0; });
The only information that is being extracted from the lambda is whether or not n2 == n1.

It does not work like C-style strcmp functions, which return a negative, 0, or positive value (this is what I was trying to say in my previous post when talking about compare). Similarly, it is different than the C function qsort, which expects a "comparator" function that returns negative, 0, or positive values.

_________________________________________

Furthermore, the function/lambda passed into sort MUST meet the requirements of what C++ calls the "Compare" requirement: https://en.cppreference.com/w/cpp/named_req/Compare

One of the rules for this is,
If comp(a,b)==true then comp(b,a)==false


For your function both (4 - 3) != 0 and (3 - 4) != 0 return true, so your function does not have "strict weak ordering" (see link above).
Last edited on
Thanks Ganado!

What you wrote above is equivalent to:
sort(begin(number), end(number), [](int n1, int n2) { return (n2 - n1) != 0; });
The only information that is being extracted from the lambda is whether or not n2 == n1.


I am confused here because I thought it's equal to [](int n1, int n2) { return n2>n1; }

But (n2-n1) will return True if (n2-n1) != 0 .

My bad
Last edited on
Not sure if that was a statement or another question, so I'll just add a bit more regardless:

I am confused here because I thought it's equal to ... return n2 > n1;
The sort function expects the return value of the function/lambda passed into it to return bool, not int. But in C/C++, every non-zero integer value is implicitly convertible into 'true'.

In other words, both -1 and +1 are converted into bool 'true' because the sort function's compare expects a bool return value.

So, as long as n2 does not equal n1, n2 - n1 will result in a non-zero value, and this non-zero value will be considered 'true'. Both (3 - 4) and (4 - 3) will result in 'true', so the ordering between 3 and 4 is not well-defined.
Last edited on
Topic archived. No new replies allowed.