Ответ 1
template<typename ReturnT, typename... ParamT>
void foo(std::function<ReturnT(ParamT...)> callback)
{}
теперь foo<int,int>
является foo<ReturnT=int, ParamsT starts with {int}>
.
Он не полностью определяет ParamT
. Фактически, нет возможности полностью указать ParamT
.
Как неполностью указанный шаблон, происходит дедукция и не выполняется. Он не пытается "что, если я просто предполагаю, что пакет больше не идет".
Вы можете исправить это с помощью:
template<typename ReturnT, typename... ParamT>
void foo(block_deduction<std::function<ReturnT(ParamT...)>> callback)
{}
где block_deduction
выглядит так:
template<class T>
struct block_deduction_helper { using type=T; }:
template<class T>
using block_deduction = typename block_deduction_helper<T>::type;
теперь дедукция блокируется по первому аргументу foo
.
И ваш код работает.
Конечно, если вы перейдете в std::function
он больше не будет автоматически выводить аргументы.
Обратите внимание, что вывод типа типа стирания типа aa, такого как std::function
, обычно является запахом кода.
Замените оба:
template<class F>
void bar(F callback)
{}
если вы должны получить аргументы, используйте помощники свойств функций (их много на SO). Если вам просто нужно вернуть значение, есть признаки std
которые уже работают.
В c++17 вы можете сделать это:
tempate<class R, class...Args>
void bar( std::function<R(Args...)> f ) {}
template<class F>
void bar( F f ) {
std::function std_f = std::move(f);
bar(std_f);
}
с помощью функции c++17.