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
, то этобольше не будет автоматически выводить аргументы.
Обратите внимание, что вывод типа стирания типа a, такого как 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 .