2016-07-29 82 views
1

我有以下功能:當參數包括std :: function ...時,C++模板參數演繹失敗,錯誤爲「候選模板被忽略」...爲什麼?

template <class InType, class OutType> 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
{ 
    return func(a); 
} 

template <class T> 
T bar(T a, T b) 
{ 
    return a + b; 
} 

我可以給他們打電話,像這樣:

double x = foo<int, double>(1, [] (const int &v) { return float(v) * 1.5f; }); 
double y = bar<int>(1.0, 2.0); 

...,並與酒吧

double z = bar(1.0, 2.0); 

使用模板實參推演......但如果我嘗試使用foo使用模板參數演繹:

double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 

它失敗,此錯誤:

no matching function for call to 'foo' 
    double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 
       ^~~ 
note: candidate template ignored: could not match 'function<type-parameter-0-1 (const type-parameter-0-0 &)>' against '(lambda at ../path/to/file.cpp:x:y)' 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
     ^

這是爲什麼?從我的觀點來看,很明顯什麼樣的參數類型應該被推斷爲。

回答

2

類型扣減不考慮隱式轉換,這在稍後的重載解析期間會發生。如果你直接傳遞一個std ::函數,它會正確推導出來。它不能隱式地從你的lambda構建一個std::function而不知道std::function是否可能。我知道,看起來編譯器有足夠的信息來正確推斷所涉及的類型,但這是一個限制。

+0

類型扣除僅考慮* some *隱式轉換。不涉及轉換構造函數。 – Brian

+0

這種情況太糟糕了。否則就可以表達一些權力邏輯,而不需要C++的典型冗長和模板模糊。 – GuyGizmo

相關問題