Привет, сообщество и с наступающим Новым Годом!
Решая одну задачу, придумал интересный макрос, позволяющий сортировать объекты по определенному полю. Получается очень лаконично, но требует 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));
Автокомментарий: текст был обновлен пользователем BekzhanKassenov (предыдущая версия, новая версия, сравнить).
В С++14 можно обойтись обойтись только названием поля, потому что там в лямбдах можно писать auto вместо типа.
Спасибо, не знал.
Изначально я так и попытался, но не скомпилировалось в C++11.
Существуют ли OJ, поддерживающие C++14?
Если я не путаю, CodeChef
Я бы, на всякий случай, написал
[](const auto &a, const auto &b)
, чтобы не искать в стандарте, как же именно передается в лямбду обычныйauto
— по значению (может долго работать из-за копирования больших структур), или же, по ссылке.Паранойя, конечно, но в подобных ситуациях предпочитаю сделать "точно правильно" и больше об этом не думать.
Исправлено.
MikeMirzayanov, давайте изменим 1 символ в строчке компиляции
It is very useful! Thank you :)
Добавьте пример set с сортировкой по полю, если он есть. В Java это есть, например TreeSet set = new TreeSet((a, b) -> { return a.x.compareTo(b.x); });
Я не нагуглил ничего лучше, чем:
Минусы: теряется лаконичность, тяжелее запомнить. Проще использовать функтор.
Автокомментарий: текст был обновлен пользователем BekzhanKassenov (предыдущая версия, новая версия, сравнить).
Auto comment: topic has been updated by BekzhanKassenov (previous revision, new revision, compare).
UPD: не заметил что топик есть и на английском, заменил этот комментарий на комментарий на английском (см ниже).
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.One can go even further and do smth like this:
(decltype is to avoid manual typing of the type name)
Then one can write: