簡體   English   中英

模板仿函數不能推導出引用類型

[英]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()重載的函數對象。 但是你要面對的問題是必須知道它是否需要引用。 要解決它, boostreference_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM