Как отсортировать вектор пар на основе второго элемента пары?

Если у меня есть вектор пар:

std::vector<std::pair > vec; 

Есть ли и простой способ сортировки списка в порядке возрастания на основе второго элемента пары?

Я знаю, что могу написать небольшой функциональный объект, который будет выполнять эту работу, но есть ли способ использовать существующие части STL и std::less для непосредственной работы?

EDIT: Я понимаю, что я могу написать отдельную функцию или class, чтобы перейти к третьему аргументу для сортировки. Вопрос в том, могу ли я построить его из стандартных материалов. Я бы действительно выглядел так:

 std::sort(vec.begin(), vec.end(), std::something_magic()); 

Вы можете использовать boost следующим образом:

 std::sort(a.begin(), a.end(), boost::bind(&std::pair::second, _1) < boost::bind(&std::pair::second, _2)); 

Я не знаю стандартный способ сделать это в равной степени коротким и лаконичным, но вы можете захватить boost::bind это все, состоящее из заголовков.

EDIT : используя c ++ 14, лучшее решение очень легко написать благодаря lambdas, который теперь может иметь параметры типа auto . Это мое настоящее любимое решение

 std::sort(v.begin(), v.end(), [](auto &left, auto &right) { return left.second < right.second; }); 

Просто используйте пользовательский компаратор (это необязательный третий аргумент для std::sort )

 struct sort_pred { bool operator()(const std::pair &left, const std::pair &right) { return left.second < right.second; } }; std::sort(v.begin(), v.end(), sort_pred()); 

Если вы используете компилятор C ++ 11, вы можете написать то же самое с помощью lambdas:

 std::sort(v.begin(), v.end(), [](const std::pair &left, const std::pair &right) { return left.second < right.second; }); 

EDIT : в ответ на ваши изменения на ваш вопрос, вот некоторые мысли ... если вы действительно хотите быть творческими и сможете многократно использовать эту концепцию, просто создайте шаблон:

 template  > struct sort_pair_second { bool operator()(const std::pair&left, const std::pair&right) { Pred p; return p(left.second, right.second); } }; 

то вы тоже можете это сделать:

 std::sort(v.begin(), v.end(), sort_pair_second()); 

или даже

 std::sort(v.begin(), v.end(), sort_pair_second >()); 

Хотя, честно говоря, все это немного переборщило, просто напишите 3-строчную функцию и сделайте с ней 😛

С C ++ 0x мы можем использовать lambda-функции:

 using namespace std; vector> v; . . sort(v.begin(), v.end(), [](const pair& lhs, const pair& rhs) { return lhs.second < rhs.second; } ); 

В этом примере вывод типа bool неявно выводится.

Типы возврата Lambda

Когда lambda-функция имеет один оператор, и это оператор return, компилятор может выводить возвращаемый тип. Из C ++ 11, §5.1.2 / 4:

...

  • Если составной оператор имеет форму { return expression ; } { return expression ; } тип возвращаемого выражения после преобразования lvalue-to-rvalue (4.1), преобразования между массивами и указателями (4.2) и преобразования функции в указатель (4.3);
  • в противном случае, void .

Чтобы явно указать тип возврата, используйте форму []() -> Type { } , например, в:

 sort(v.begin(), v.end(), [](const pair& lhs, const pair& rhs) -> bool { if (lhs.second == 0) return true; return lhs.second < rhs.second; } ); 

Его довольно просто вы используете функцию сортировки из алгоритма и добавляете свою собственную функцию сравнения

 vector< pair > v; sort(v.begin(),v.end(),myComparison); 

Теперь вам нужно сделать сравнение на основе второго выбора, поэтому объявите «myComparison» как

 bool myComparison(const pair &a,const pair &b) { return a.second 

Для чего-то многоразового использования:

 template 

Вы можете использовать его как

 std::sort(foo.begin(), foo.end(), compare_pair_second<>()); 

или

 std::sort(foo.begin(), foo.end(), compare_pair_second()); 

Вы должны полагаться на нестандартный select2nd

Попробуйте поменять элементы пар, чтобы вы могли использовать std::sort() как обычно.

  • Создание карты :: поиск недействителен
  • Что стандартная библиотека гарантирует самопереключение?
  • C ++ конвертировать вектор в вектор
  • Поиск C ++ STL-подобного векторного classа, но с использованием хранилища стека
  • Ли вектор :: erase () на векторе указателей объектов уничтожает сам объект?
  • Использование STL-карты указателей функций
  • Контейнеры стандартной библиотеки с дополнительными параметрами шаблона?
  • Почему поведение инициализатора C ++ для std :: vector и std :: array отличается?
  • Почему стандартные iteratorы диапазона вместо ?
  • Как распечатать элементы вектора C ++ в GDB?
  • std :: string :: c_str () и временные
  • Interesting Posts

    Что возвращает sizeof (& array)?

    В чем смысл «__attribute __ ((упакованный, выровненный (4)))»

    Обновить данные, полученные с помощью специальной функции в Листе Google

    Получить текущее имя представления в ASP.NET MVC?

    Используйте триггер для остановки вставки или обновления

    JQuery: определить, нажата ли нажата средняя или правая кнопка мыши, если да, сделайте следующее:

    Переменная, измененная внутри цикла while, не запоминается

    Обход MySQL Ошибка «Невозможно повторно открыть таблицу»

    Как настроить HttpContent для второго параметра HttpClient PostAsync?

    Как определить основную причину плохого охлаждения ноутбука?

    Табличное представление Javafx не показывает данные во всех столбцах

    Действие параметра , в котором T3 может быть необязательным

    Объединение нескольких заданий MapReduce в Hadoop

    Сбросьте или удалите пароль BIOS на моем ноутбуке

    Подтвердите JSON против JSON Schema C #

    Давайте будем гением компьютера.