Расширение лямбда-выражений, допускающее перегрузку оператора ()

pooh
pooh

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

- Передача разных коллбэков для штатного продолжения и обработки ошибок в асинхронном коде

- Использование различных обработчиков для возвращаемого значения и исключения в completable future

Передача двух отдельных лямбд хороша до тех пор, пока им не нужно захватывать одни и те же переменные. Как только обеим лямбдам нужна одна и та же переменная, мы либо должны делать лишнее копирование, либо, если переменная move-only, искать обходные пути, которые зачастую неэффективны. Чаще всего проблема возникает именно в асинхронном коде, когда мы не можем захватывать объекты по ссылке. Возможность перегрузки оператора () устраняет эту проблему.

С точки зрения синтаксиса такая конструкция может быть описана, например, так (пример полностью синтетический):

auto l = [a, b = std::move(b)]
[
    (int x) -> auto { return a.f(x); },
    (char* x) -> auto { return b.g(x); }
];

 

-4
рейтинг
7 комментариев
pooh

P.S. По сути, множественность оператора () у нас уже есть из-за наличия auto, когда этот оператор становится шаблонным. Предлагаемое изменение обеспечивает полноту возможностей по перегрузке этого оператора.

pooh
Владимир Топунов

C++ pattern matching, по-моему лучше

https://habr.com/ru/post/282630/

Владимир Топунов
pooh

Pattern matching решает ортогональную проблему, и на эту тему существует много различных подходов. Здесь же речь идет о том, что, в случае pattern matching, мы хотим иметь возможность захватывать контекст, причем один и тот же контекст для всех участвующих лямбд.

Основная фишка в том, что предлагаемое расширение не требует никаких изменений с точки зрения реализации лямбд компиляторами. Это своего рода синтаксический сахар, но не выразимый существующими средствами языка.

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

pooh
Обновлено 
m0xf

Задачу можно решить с помощью if constexpr внутри lambda-функции. 

m0xf
pooh

m0xf, в части случаев - да, можно использовать лямбду с auto и дальше сравнивать типы, но это не слишком элегантно и не работает, когда количество аргументов в одном и в другом случае разное (там тоже можно извратиться с auto..., но это уже совсем за гранью добра и зла). Плюс в этом случае не работает приведение типов при передаче параметров, этот тоже вызывает определенные сложности .

pooh
Daniil Goncharov

Возможно подойдет одно из следующих предложений?
https://github.com/cplusplus/papers/issues/281

https://github.com/cplusplus/papers/issues/527

Daniil Goncharov
pooh

Нет, эти предложния по сути используют различные лямбды, каждая со своим списком захваченных переменных. А как раз основная суть моего предложения - разрешить своего рода "мультилямбды", имеющие один список захваченных переменных, но допускающие перегрузку для разных наборов параметров. С точки зрения реализации это потребует минимальных усилий.

pooh
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения