Должен ли std:: sort работать с лямбда-функцией в С++ 0x/С++ 11?

Я попытался использовать лямбда-функцию с sort, но получал ошибки "Ошибка сегментации". Мне удалось упростить код до следующего:

#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;
}

Я компилирую и запускаю этот код в Ubuntu 11.04 (x64) с помощью

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

Он печатает много пар формы (large_integer, 1008), пару (0, 1008) и выходит с "Ошибка сегментации".

Ответ 1

Предикат сравнения должен возвращать bool: true, если a < b и false в противном случае. Измените оператор return на:

  return a < b;

Не путайте его с 3-сторонними функциями сравнения C-стиля.

Ответ 2

Предикат должен реализовывать простой, слабый порядок. Также ваш диапазон отключен, если вы хотите отсортировать всю вещь. (я пропустил это намеренное.) Итак, все мы ищем что-то вроде этого:

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

Или даже:

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

Предикат по умолчанию для сортировки std::less<T>, который делает именно то, что делает лямбда.

Ответ 3

Предикат для std::sort не принимает Java-like -1,0,1, но вместо этого хочет, чтобы вы возвращали логическое значение, которое отвечает на вопрос "Является первым аргументом меньше второго аргумента?", который используется для слабо упорядочить элементы. Поскольку -1 является ненулевым значением, оно считается истинным по алгоритму сортировки, и это приводит к тому, что алгоритм имеет пробой.