Блог пользователя BekzhanKassenov

Автор BekzhanKassenov, история, 11 лет назад, По-русски

Привет, сообщество и с наступающим Новым Годом!

Решая одну задачу, придумал интересный макрос, позволяющий сортировать объекты по определенному полю. Получается очень лаконично, но требует C++11. Собственно, макрос:

#define by(T, x) [](const T& a, const T& b) { return a.x < b.x; }

Использование:

struct Item {
    int a, b;
};

sort(arr, arr + N, by(Item, a));

Полный пример: http://pastebin.com/Cp5ZkwE4.

Всем счастливого нового года!

UPD: В комментариях указали, что C++14 позволяет еще короче:

#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; }
sort(arr, arr + N, by(a));
  • Проголосовать: нравится
  • +122
  • Проголосовать: не нравится

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Автокомментарий: текст был обновлен пользователем BekzhanKassenov (предыдущая версия, новая версия, сравнить).

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +24 Проголосовать: не нравится

It is very useful! Thank you :)

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Добавьте пример set с сортировкой по полю, если он есть. В Java это есть, например TreeSet set = new TreeSet((a, b) -> { return a.x.compareTo(b.x); });

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Автокомментарий: текст был обновлен пользователем BekzhanKassenov (предыдущая версия, новая версия, сравнить).

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Auto comment: topic has been updated by BekzhanKassenov (previous revision, new revision, compare).

»
11 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +10 Проголосовать: не нравится

UPD: не заметил что топик есть и на английском, заменил этот комментарий на комментарий на английском (см ниже).

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Just for the fun, it is possible to do the same in c++03 without using any macro. It is not as short macro version, but at least you can't break it by passing something like x || 3 to it.

template<class T, class R, R T::* x> struct by {
    bool operator()(const T& a, const T& b) { return a.*x < b.*x; }
};

sort(arr, arr + N, by<Item, int, &Item::a>());
»
11 лет назад, скрыть # |
 
Проголосовать: нравится +27 Проголосовать: не нравится

One can go even further and do smth like this:

#define by(T, ...) [](const decltype(T)& a, const decltype(T)& b) { return a.__VA_ARGS__ < b.__VA_ARGS__; }

(decltype is to avoid manual typing of the type name)

Then one can write:

vector<pair<pair<SuperCoolStruct, int>, AnotherCoolStruct>> arr;
sort(arr.begin(), arr.end(), by(arr[0], first.first.someImportantField));