[英]Template functor cannot deduce reference type
我有一個仿函數f,它接受函數func和與func相同類型的參數t。 我無法將g傳遞給f,因為編譯錯誤(沒有匹配函數來調用f(int&, void (&)(int&))
)。 如果g將采用非引用參數g(int s),則編譯完成。 或者,如果我手動指定模板參數f<int&>(i, g)
,編譯也會完成。
template<typename T>
void f(T t, void (*func)(T)) {}
void g(int& s) {}
int main(int, char*[])
{
int i = 7;
f(i, g); // compilation error here
return 0;
}
我怎樣才能得到演繹?
您可以像這樣調用函數:
f<int&>(i, g);
但現在我也將通過參考傳遞。
一般來說,我也將該函數設為模板類型:
template <typename T, typename F>
void f(T t, F func)
{
func(t); //e.g
}
我想你需要:
void f(T t, void (*func)(T&)) {}
要么:
void g(int s) {}
但是我更喜歡:
template<typename T, typename T2>
void f(T t, T2 func) {}
因為這將適用於函數和函子。
問題是如果在模板中,其中一個函數參數在推導開始之前不是引用類型,那么該參數將永遠不會推導為引用類型。 所以在左側的推論中, T
得出int
,但是在右側的推論中, T
得到int&
。 這是一個錯誤的匹配,編譯器抱怨。
最好的方法是使函數參數與函數指針的參數類型相同:
template<typename T> struct identity { typedef T type; };
template<typename T>
void f(typename identity<T>::type t, void (*func)(T)) {}
通過使用identity<T>::type
,可以在左側禁用演繹。 一旦在右側確定T
,則將T
置於左側並產生最終參數類型。
一個人建議將右側作為模板參數 - 這是一件好事,因為它可以接受帶有operator()
重載的函數對象。 但是你要面對的問題是必須知道它是否需要引用。 要解決它, boost
有reference_wrapper
(順便說一下, boost
也有上面的identity
模板)。
template<typename T, typename F>
void f(T t, F func) {}
現在,如果你想傳遞引用而不是副本,你可以這樣做
int i;
f(boost::ref(i), some_function);
ref
返回一個reference_wrapper對象,該對象可以隱式轉換為T&
。 因此,如果調用func(t)
, t
將自動轉換為目標引用。 如果您不想傳遞引用,請直接傳遞i
。
template<typename T>
void f(T t, void (*func)(T)) {}
這里的關鍵是你在兩個參數中都使用了T
這意味着類型必須完全匹配。
void g(int& s) {}
int i = 7;
f(i, g);
在你的代碼中,你傳遞一個int
和一個帶有int&
到f()
的函數。 這些是不同的類型,但你的f
模板需要兩個相同的類型。 正如其他人所建議的那樣,最簡單的修復方法是將該函數作為模板。
template <typename T, typename F>
void f(T t, F func)
{
func(t);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.