cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

ref-qualified operator () for lambda closure classes #254

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +4, -2 Автор идеи: webreh

Стандарт C++11 расширяет объявление non-static member functions понятием ref-qualifier, который влияет на возможность вызова соответствующей функции по lvalue reference и rvalue reference, тем самым обязывая вызывающего указать ссылку на постоянный или временный объект. Для operator() синтезированных лямбда-классов указание ref-qualifier невозможно.

Предлагается дополнить синтаксис лямбда-выражений указанием ref-qualifier. Наиболее очевидным кажется синтаксис с указанием после опционального спецификатора mutable/constexpr

[captures] <tparams> (params) specifiers ref-quailifier exception attr {}

Использование: например, для лямбда-выражений с захватом MoveConstructible объектов и последующей однократной сборкой результирующего объекта максимально естественным является указание operator() как &&.

apolukhin commented 3 years ago

Antervis, 22 декабря 2017, 8:38 ref-qualifier нужен для выполнения перегрузок. Лямбды не поддерживают перегрузки. Это может быть актуально только после введения в стандарт P0051 - generic overload function, но и даже в этом случае ref-qualifier лучше задавать в виде шаблонного параметра/аргумента overload, а не сигнатуры лямбды

Andrey Davydov, 22 декабря 2017, 16:40

ref-qualifier нужен для выполнения перегрузок

Не только. Еще, если я хочу чтобы тот кто будет вызывать мою лямбду сделал это не больше одного раза (что очень естественно для callback'ов). Т.е. я хочу чтобы мою лямбду можно было вызвать из такой функции template void invoke_once(F && f) { std::move(f)(); } но нельзя было бы из такой:

template<typename F> void invoke(F && f) { f(); }

webreh, 22 декабря 2017, 19:40 Antervis, ref-qualifier и const нужен не для выполнения перегрузок, а для указания характера передачи формального параметра в *this. Например, для внешней функции для std::uniqueptr detach(some&& object) { return std::move(object.inner); } точная запись будет struct some { std::uniqueptr detach() && { return std::move(inner); } std::uniqueptr inner; };

Antervis, 25 декабря 2017, 6:12 webreh, я так полагаю, вы хотите чтобы ref-qualifier && указывал, что лямбда может выполняться только однократно?

webreh, 25 декабря 2017, 14:05 Antervis, да, мне кажется, что это наиболее естественное в текущем языке указание однократного выполнения функции.

languagelawyer, 26 мая 2018, 7:01 Andrey Davydov, что помешает сделать

std::move(f)(); std::move(f)();

???

Andrey, 26 мая 2018, 9:31 languagelawyer, совесть или static analyzer (clang-tidy [bugprone-use-after-move])