Constantine
Ну там совершенная глупость
Constantine
Просто опущен простейший параметр
Constantine
Который напрямую отправляется на сигнатуру operator ()
Constantine
там в действительности типовое
button.reset_is_enabled(
utils::reactive::make_binary_function(
utils::create(SomeSource1), utils::create(SomeSource2), [](auto value1, auto value2) {
return some condition with value1 and value2;
}
)
)
Constantine
ну вот совсем не хочется на каждое такое С-стайлом функцию объявлять
Constantine
это не про предложение
Constantine
к предложению относится буквально то, что в комментариях
Constantine
вопрос: зачем нужен && для функций?
Constantine
ответ: потому что однократно вызываемая функция вызывается как
call_once(once_callable_function<std::unique_ptr<int>()>&& function)
Constantine
Именно
Constantine
Лямбда МОЖЕТ быть разрушена вызовом
Constantine
operator ()
Constantine
?
Constantine
Constantine
у меня лямбда захватила std::unique_ptr
Constantine
и хочет вернуть
Constantine
ага
Constantine
если бы это была не лямбда, я бы писал сигнатуру &&
Constantine
а лямбде не могу
Constantine
потому что нет ref quailfier
Constantine
я могу написать
Constantine
а еще я могу написать
T& operator [](size_t ndx)
Constantine
Я не вызываю лямбду руками, я врапаю ее в once_callable_function
Constantine
И мне принципиально знать, что эту лямбду можно врапать в once_callable_function и нельзя в multiple_callable_move_constructible_function
Constantine
разница между ними очень простая - первая на самом деле аналогична вызову в non-member версии
void inlambda_call_operator(closure_class&& this_reference)
Constantine
а вторая
void inlambda_call_operator(closure_class& this_reference)
Constantine
Я использую лямбды в том числе для того, чтобы записывать builder объекты и передавать события на основной поток
Constantine
Где builder по определению once callable factory
Constantine
Anatoliy
Constantine
просто ощути разницу
template <typename T>
struct builder_interface {
virtual T build() && = 0;
};
и
template <typename T>
struct every_object_is_registered_factory_interface {
virtual T create() = 0;
};
Constantine
Anatoliy
virtual - это существенно?
Constantine
это интерфейс
Anatoliy
builder_interface или every_object_is_registered_factory_interface имеют поля?
Constantine
теперь подумай, соответствует ли
auto x = std::make_unique< int >(42);
auto l = [x = std::move(x)] () mutable -> auto { return std::move(x); };
первому и соответствует ли второму
Anatoliy
или можно вообще от виртуальности избавиться
Anatoliy
я пока задачи не вижу. только намёки
Constantine
задача: у тебя существует два типа функций. Один из этих типов можно вызывать много раз, другой тип - не более одного раза
Anatoliy
auto x = std::make_unique< int >(42);
auto l = [x = std::move(x)] () mutable -> auto { assert(x); return std::move(x); };
Constantine
Constantine
а теперь представь
Constantine
auto x = std::make_unique< int>(42);
auto l = [x = std::move(x)] () mutable && -> auto { return std::move(x); };
Constantine
где && означает, что у лямбды operator () имеет ref qualifier &&
Anatoliy
Constantine
что это даёт?
то, что синтаксис вызова лямбды - только по &&
Anatoliy
это тебя обяжет делать так: std::move(l)(). вот и всё
Constantine
это значит, что теперь не lambda(), а std::move(lambda)()
Constantine
именно
Anatoliy
волшебства не произойдёт
Constantine
произойдет
Anatoliy
нет.
Constantine
потому что std::move на одну переменную нехрен писать дважды
Anatoliy
у тебя даже нет ворнинга, чтобы задетектить use after move
Constantine
но у меня не тупая обезьяна за монитором
Constantine
а еще у меня есть типы-обертки
Constantine
которые в случае вызова lambda() просто это не скушают
Constantine
Как только я пишу mutable, я не имею в виду чистую функцию
Constantine
давайте вернемся к примеру
Constantine
просто ощути разницу
template <typename T>
struct builder_interface {
virtual T build() && = 0;
};
и
template <typename T>
struct every_object_is_registered_factory_interface {
virtual T create() = 0;
};
Constantine
это интерфейсы
Constantine
в том самом джава смысле
Anatoliy
как раз наоборот
Constantine
Anatoliy
const у функций-членов значит, что чистая
Anatoliy
не распознал
Constantine
короче, && это та же самая разница, что в примере
template <typename T>
T build(builder_interface<T>&& builder);
template <typename T>
T create(factory_interface<T> & factory);
Anatoliy
Constantine
На самом деле ref-qualifier это почти буквально переданный *this
Ivan
я может чего не догоняю, но Константин хотел это? https://ideone.com/t6PjSv
Constantine
Constantine
ref-qualifier это буквально более строгая конвенция вызова
Constantine
во всех случаях
Ivan
ты хочешь чтобы у функции был такой тип: "функция вызываемая один раз"
Constantine
да
Ivan
и была бы ошибка компиляции если бы её вызвали два раза?
Ivan
из кода
Constantine
это невозможно достичь