fiktor
fiktor

Reputation: 1413

Should std::sort work with lambda function in c++0x/c++11?

I tried to use lambda function with sort, but was getting "Segmentation fault" errors. I managed to simplify the code to the following:

#include <iostream>
#include <algorithm>

int main()
{
  const int len = 18;
  int intArr[len];
  for (int i=0;i<len;i++) intArr[i]=1000+i;
  // The following is expected to sort all but the last element of the array
  std::sort(intArr, intArr + len -1, [](int a, int b)
    {
      std::cout<<"("<<a<<", "<<b<<")\n";
      return (a<b?-1:(a>b?1:0));
    });
  return 0;
}

I compile and run this code in Ubuntu 11.04 (x64) using

g++ -std=gnu++0x test2.cpp && ./a.out.

It prints a lot of pairs of the form (large_integer, 1008), a couple of (0, 1008) and exits with "Segmentation fault".

Upvotes: 31

Views: 22381

Answers (3)

Yakov Galka
Yakov Galka

Reputation: 72489

The comparison predicate should return a bool: true if a < b and false otherwise. Change the return statement to:

  return a < b;

Not to be confused with C-style 3-way comparison functions.

NOTE: Though C++20 does introduce a 3-way comparison operator <=>, sort would still expect a 2-way compare predicate.

Upvotes: 35

Dave S
Dave S

Reputation: 21113

The predicate for std::sort doesn't take the Java-like -1,0,1, but instead wants you to return a boolean that answers the question 'Is the first argument less than the second argument?', which is used to weakly order the elements. Since -1 is a non-zero value, it is considered true by the sort algorithm, and it causes the algorithm to have a breakdown.

Upvotes: 7

Kerrek SB
Kerrek SB

Reputation: 477100

The predicate is supposed to implement a simple, weak ordering. Also your range is off if you want to sort the entire thing. (I missed that that was intentional.) So all in all we're looking for something like this:

std::sort(intArr, intArr + nelems, [](int a, int b){ return a < b; });

Or even:

std::sort(intArr, intArr + nelems);

The default predicate for sorting is std::less<T>, which does exactly what the lambda does.

Upvotes: 16

Related Questions