Як сортувати з лямбда?


136
sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b)
{ 
    return a.mProperty > b.mProperty; 
});

Я хотів би використовувати функцію лямбда для сортування спеціальних класів замість прив'язки методу екземпляра. Однак наведений вище код дає помилку:

помилка C2564: 'const char *': перетворення стилю функції у вбудований тип може приймати лише один аргумент

Це добре працює з boost::bind(&MyApp::myMethod, this, _1, _2).


Вектор має структуру, яка містить ціле число та два рядки. Властивість тут буде цілим числом.
БТР

4
Покажіть нам невеликий компільований приклад.
GManNickG

Відповіді:


157

Зрозумів.

sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b) -> bool
{ 
    return a.mProperty > b.mProperty; 
});

Я припускав, що з'ясується, що оператор> повертає bool (за документацією). Але, мабуть, це не так.


39
Що за дурний operator>, значить.
GManNickG

2
Те, що ви написали до цього часу, мало сенсу. Якщо mProperty передбачається, що це int a.mProperty>b.mProperty, безумовно, вийде буль .
sellibitze

1
Тоді ти розумієш мою плутанину. Я думаю, що це може бути щось дивне з моїм VC10 Express (немає пакета обслуговування). Я перемістив проект на машину разом із командою Visual Studio 2010, і він працював без "-> bool".
BTR

8
Чи не повинно бути operator<, чи не так operator>?
Warpspace

8
Так, це має бути <, для стандартного порядку зростання. Я відредагував відповідь, щоб дати зрозуміти, що це був низхідний сорт, але, мабуть, моя редакція була непомітною і була витерта!
млинець

18

Щоб багато коду, ви можете використовувати його так:

#include<array>
#include<functional>

int main()
{
    std::array<int, 10> vec = { 1,2,3,4,5,6,7,8,9 };

    std::sort(std::begin(vec), 
              std::end(vec), 
              [](int a, int b) {return a > b; });

    for (auto item : vec)
      std::cout << item << " ";

    return 0;
}

Замініть "vec" своїм класом і все.


Наскільки ваша відповідь відрізняється від BTR? Btw. ви можете використовувати std :: begin (vec) і std :: end (vec), щоб зробити це більш c ++ 11.
Логман

Вибачте, я не знаю, як я це пропустив. Мої очі зупиняються на посту Стефана. Моє погано. (Я змінюю публікацію після ваших пропозицій)
Адріан

5

Чи може бути проблема з рядком "a.mProperty> b.mProperty"? Я отримав такий код для роботи:

#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
#include <sstream>

struct Foo
{
    Foo() : _i(0) {};

    int _i;

    friend std::ostream& operator<<(std::ostream& os, const Foo& f)
    {
        os << f._i;
        return os;
    };
};

typedef std::vector<Foo> VectorT;

std::string toString(const VectorT& v)
{
    std::stringstream ss;
    std::copy(v.begin(), v.end(), std::ostream_iterator<Foo>(ss, ", "));
    return ss.str();
};

int main()
{

    VectorT v(10);
    std::for_each(v.begin(), v.end(),
            [](Foo& f)
            {
                f._i = rand() % 100;
            });

    std::cout << "before sort: " << toString(v) << "\n";

    sort(v.begin(), v.end(),
            [](const Foo& a, const Foo& b)
            {
                return a._i > b._i;
            });

    std::cout << "after sort:  " << toString(v) << "\n";
    return 1;
};

Вихід:

before sort: 83, 86, 77, 15, 93, 35, 86, 92, 49, 21,
after sort:  93, 92, 86, 86, 83, 77, 49, 35, 21, 15,

Так, щось глузливе з налаштуванням, на якому я був. Компіляція на моєму ноутбуці без нього просто чудова в командній редакції Visual Studio 2010. Що втягнуло мене в те, що я повернувся назад, щоб прив’язати, і помилка не піде. Я був на VC10 Express. Помилка?
BTR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.