&&
ссылки, даже если они написаны одинаково, играют разные роли.
void set_func_1(std::function<int()>&& f) {
myFunc = std::move(f);
}
является правильным, но принимает только ссылки на r-значения.В template<typename funcT> void set_func_2(funcT&& f)
, &&
является ссылкой для пересылки , поэтому использование std::move(f)
в теле неверно - это может украсть состояние у невременного объекта.Вместо этого вам нужно будет использовать std::forward<funcT>(f)
.
Преимущество 2-й функции по сравнению с 1-й состоит не в оптимизации.Первый будет принимать только r-значения, поэтому, например, function<int> f = []{return 1;}; struct yyy; yyy.set_func_2(f);
не будет компилироваться.
Хороший, простой, почти оптимальный способ написания set()
методов - передача по значению и перемещение:
void set_func_3(std::function<int()> f) {
myFunc = std::move(f);
}
Книга Скотта Мейерса "Современный эффективный C ++" содержит более подробную информацию о ее применимости.