У меня есть шаблон функции, который принимает аргумент некоторого вызываемого типа и использует std::bind
для создания нового вызываемого объекта с предопределенными значениями аргумента для исходного вызываемого объекта.Я написал его с опорным параметром перенаправления и std::forward
, например:
template <typename F>
auto make_example_caller(F &&f) {
return std::bind(std::forward<F>(f), 123, 456, 789);
}
Документация cppreference для std::bind
говорит, что связанный объект "содержит объект-члентипа std::decay<F>::type
, построенный из std::forward<F>(f)
".Поскольку std::bind
перенаправляет функцию на свой внутренний элемент данных, перенаправление этой же функции на вызов std::bind
в моем собственном коде кажется разумным и уместным.
Однако неясно, какую пользу это дает.Если F
является ссылочным типом, std::decay
удаляет ссылку, поэтому объект связывания будет хранить свой собственный экземпляр вызываемого типа.Этот экземпляр будет создан как ход, если F
является ссылкой на rvalue, или копия, если F
является lvalue, и я могу получить тот же результат, если напишу свою функцию следующим образом:
template <typename F>
auto make_example_caller(F f) { // Note, no &&
return std::bind(std::move(f), 123, 456, 789); // move, not forward
}
Теперь собственный параметр f
моей функции будет инициализироваться либо перемещением, либо копированием, в зависимости от того, как вызывается функция, но в любом случае у меня теперь есть свой собственный экземпляр объекта функции, который я могу переместить в объект связывания.
Последний способ кажется более простым, но мне интересно, если я что-то упустил - тем более, что те же рассуждения применимы к самому std::bind
, но для этого нужно F&&
и пересылать его вместо F
по значению и перемещая его.Есть ли недостаток в этом?Что-то, чего я не вижу?