Проблема заключается в том, что нужно избегать копий.
Представьте себе:
auto lambda = [ptr = std::make_unique<int>(0)]() mutable {
std::cout << *ptr;
ptr = std::make_unique<int>(*ptr + 1); // why not?
};
MyFunc(lambda); // use it normally
MyFunc([]{ std::cout << " end"; }); // use by using a temporary lambda
lambda() // just call the function after that
Если подпись MyFunc(Function f)
, потребуется std::move
, а лямбда не будет использоваться после вызова.
Если подпись MyFunc(Function const& f)
, она не будет работать, поскольку лямбда-код является изменяемой.
Если она была MyFunc(Function& f)
, то временная переменная не будет работать.
Вы в основном остались с MyFunc(Function&& f)
.
Реальный вопрос, однако, таков: «Нужно ли мне поддерживать все эти случаи?»
Я бы сказал: большинство время нет. В большинстве случаев получение лямбды по значению является самым простым и поддерживает почти все случаи. Так пошел STL.
Почему? Потому что идеальную пересылку функциональных объектов действительно трудно получить идеальной, и вы не можете вызывать функцию несколько раз в большинстве случаев совершенно обычным образом c. Я бы предпочел переслать функцию, только если я хочу обернуть ее, хочу полностью избежать копий, и я ожидаю, что функциональные объекты, которые являются квалифицированными для временных.