[英]How to have template type deduced in std::function arguments with lambda?
[英]Lambda is deduced to std::function if template has no variadic arguments
template<typename ReturnT, typename... ParamT>
void foo(std::function<ReturnT(ParamT...)> callback)
{}
template<typename ReturnT, typename ParamT>
void bar(std::function<ReturnT(ParamT)> callback)
{}
main()
{
foo<int, int>([](int x){ return x; }); // no instance of function
// template matches argument list
bar<int, int>([](int x){ return x; }); // OK
}
foo和bar之間的唯一區別是foo具有可變參數。 不知何故,編譯器能夠將lambda轉換為bar中的std :: function。
據我所知,模板類型推導不考慮類型轉換。 那么兩個都不應該失敗嗎?
您沒有對bar
的類型參數進行任何扣除,它們是完全指定的。
你仍然可以在foo
推斷包的尾部,並且因為lambda不是std::function
而失敗。
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
,它將不再自動推斷出參數。
請注意,推斷類型擦除類型的類型如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演繹指南功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.