Как сортировать с лямбдой?


138
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).


Вектор представляет собой структуру, содержащую целое число и две строки. Свойство здесь будет целым числом.
BTR

4
Покажите нам небольшой компилируемый пример.
GManNickG

Ответы:


159

Понял.

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, определенно будет получено значение типа bool.
sellibitze

1
Тогда вы понимаете мое замешательство. Я думаю, что с моим VC10 Express (без пакета обновлений) может быть что-то странное. Я переместил проект на компьютер с Visual Studio 2010 Team, и он работал без "-> bool".
BTR

8
Не должно ли быть operator<, не так operator>ли?
Warpspace

8
Да, это должно быть <в стандартном порядке возрастания. Я отредактировал ответ, чтобы было ясно, что это нисходящий вид, но, по-видимому, мое редактирование было бесполезным и было стерто!
блин

19

Для большого количества кода вы можете использовать его так:

#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" на свой класс и все.


Чем ваш ответ отличается от БТР? Btw. вы можете использовать std :: begin (vec) и std :: end (vec), чтобы сделать его больше с ++ 11.
Logman 08

Извините, я не знаю, как я это пропустил. Мой взгляд останавливается на посте Стефана. Мое плохое (я
Адриан

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,

Да, что-то не так с настройкой, на которой я был. Компиляция на моем ноутбуке без этого просто отлично подходит для Team edition Visual Studio 2010. Что подсказало мне, что я переключил обратно на привязку, и ошибка не исчезнет. Я был на VC10 Express. Ошибка?
BTR
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.