[英]Why can std::function not accept a deduced type as its template parameter?
[英]Substitution failure with `std::function` and previously deduced template parameter - why?
考慮以下代碼:
template <typename>
struct S { };
void g(S<int> t);
template <typename T>
void f(T, std::function<void(S<T>)>);
嘗試調用時
f(0, g);
我收到以下錯誤:
error: no matching function for call to 'f' f(0, g); ^ note: candidate template ignored: could not match 'function<void (S<type-parameter-0-0>)>' against 'void (*)(S<int>)' void f(T, std::function<void(S<T>)>); ^
雖然我知道通常不能推斷
std::function
參數的類型,因為它是非推斷上下文
在這種情況下, T
可以首先由傳遞的參數0
推斷,然后代入std::function<void(S<T>)>
以獲得std::function<void(S<int>)>
。
我希望在推導T=int
之后,編譯器會在簽名中的任何地方替換T
,然后嘗試使用參數g
構造std::function
參數。
為什么不是這樣? 我認為替換/扣除發生的順序與此有關,但我想看看相關的標准措辭。
額外的問題:這是否可以在未來的標准中進行更改,同時保持向后兼容性,或者這種替代不起作用的根本原因是什么?
雖然我知道通常 std::function 參數的類型無法推斷,因為它是非推斷上下文。
它不是一個非推斷的上下文。 恰恰相反。 由於嘗試對std::function
的參數進行推導,但參數不是std::function
,因此推導失敗。 The deduction of template arguments from function arguments must agree for all function arguments. 如果它失敗了,它就完全失敗了。
[temp.deduct.type]
2在某些情況下,使用單個類型 P 和 A 的集合進行推導,在其他情況下,將有一組對應的類型 P 和 A。類型推導是對每個 P/A 對獨立進行的,並且推導的然后組合模板參數值。 如果不能對任何 P/A 對進行類型推導,或者如果對任何 P/A 對的推導導致不止一組可能的推導值,或者如果不同的對產生不同的推導值,或者如果任何模板參數既不是推導的也不是顯式的指定,模板參數推導失敗。
將第二個 function 參數的類型變成非推斷上下文實際上是克服錯誤的方法。
#include <functional>
template<typename T>
struct type_identity {
using type = T;
};
template <typename>
struct S { };
void g(S<int> ) {}
template <typename T>
void f(T, typename type_identity<std::function<void(S<T>)>>::type) {}
int main() {
f(0, g);
}
T
從第一個 function 參數成功推導出來,沒有什么可推演的了。 所以推論被認為是成功的。
雖然我知道通常
std::function
參數的類型無法推斷,因為它是非推斷上下文,但在這種情況下,T
可以首先由傳遞的參數0
推斷。
這不是真的。 T
在這種情況下是可推導出的。 如果您將代碼更改為
template <typename T>
void f(std::function<void(S<T>)>);
int main()
{
f(std::function<void(S<int>)>(g));
}
代碼將編譯並正確推導出T
您的問題是您將 object 傳遞給無法從中提取T
的 function 。 編譯器在嘗試推斷T
時不會對 function arguments 進行任何轉換。 這意味着您有一個int
和一個 function 作為傳遞給 function 的類型。 它從0
獲取int
,然后嘗試從您傳入第二個參數的std::function
獲取類型,但由於您沒有傳遞std::function
它無法提取T
,因此,您得到一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.