2011-04-11 41 views
1

我想下面的代碼重載一個簡單的函數來爲多種類型工作。但是,它不能編譯。有人可以告訴我什麼是錯的,以及如何解決這個問題?模板代碼returntype重載不編譯。什麼是錯的

typedef struct str1_type 
{ 
    int f1; 
    int f2; 
} STR1; 

typedef struct str2_type 
{ 
    char f1[100]; 
    char f2[100]; 
}STR2; 

template <typename T1, typename T2> 
T2 getFieldOffset(const T1& t, int i); 

int main() { 

    STR1 str1; 
    STR2 str2; 

    int i = getFieldOffset(str1,0); 

    const char* test = getFieldOffset(str2,0); 

} 

template <typename T1, typename T2> 
T2 getFieldOffset(const T1& t, int i) 
{ 
    switch (i) { 
     case 0: 
      return t.f1; 
     case 1: 
      return t.f2; 
     default: 
     { 
      cout << "Invalid index passed: i" << i << endl; 
      return null; 
     } 
    } 
} 

以下是錯誤消息:

test2.cpp: In function 'int main()':
test2.cpp:73: error: no matching function for call to 'getFieldOffset(STR1&, int)'
test2.cpp:75: error: no matching function for call to 'getFieldOffset(STR2&, int)'

test2.cpp: In function 'T2 getFieldOffset(const T1&, int)':
test2.cpp:90: error: 'null' was not declared in this scope

+0

那麼,你收到什麼錯誤信息? – yan 2011-04-11 15:51:32

+0

剛更新錯誤消息。對不起,以前錯過它 – Kiran 2011-04-11 15:54:11

回答

8
template <typename T1, typename T2> 
T2 getFieldOffset(const T1& t, int i); 

只有模板參數T1可以從參數可以推斷,所以你必須明確地提供模板參數列表模板參數T2,當你撥打電話。

但是,如果按照書面使用函數模板,則必須爲兩個模板參數提供參數。您應該交換的T1T2的位置在模板參數列表,所以你只需要指定T2

template <typename T2, typename T1> 
T2 getFieldOffset(const T1& t, int i); 

或者,用更好的名稱爲模板參數:

template <typename TReturn, typename T> 
TReturn getFieldOffset(const T& t, int i); 

現在,您可以稱爲:

getFieldOffset<ReturnType>(str1,0); 
4

編譯器無法推斷返回類型。一個原因是因爲getFIeldOffset可能會返回非int的值,但可以轉換爲int。當返回類型是必須指定:

getFieldOffset<STR2,int>(str2,0); 
1
int i = getFieldOffset(str1,0); 
const char* test = getFieldOffset(str2,0); 

getFieldOffset是一個函數模板採用兩個類型參數。但是在上面的代碼中,你沒有提供類型參數。你希望編譯器推斷它們。但編譯器只能推導出函數參數類型,而不是返回類型。因此錯誤。

您對提供這兩種類型的參數:

int i = getFieldOffset<STR1, int>(str1,0); 
const char* test = getFieldOffset<STR2, char*>(str2,0); 

但是,如果你在函數模板作爲

template <typename T1, typename T2> 
T1 getFieldOffset(const T2& t, int i); //T1 (i.e 1st type) becomes returnType!! 

逆轉的類型順序然後你就可以只提供一種類型,返回類型,在調用函數時;另一種類型可以從函數參數中推導出來:

int i = getFieldOffset<int>(str1,0); 
const char* test = getFieldOffset<char*>(str2,0); 
2

看起來你應該寫NULL而不是null,它的所有功能都可以正常工作。

In function 'T2 getFieldOffset(const T1&, int)': test2.cpp:90: error: 'null' was not declared in this scope 

的問題是在模板實例,編譯器無法實例化模板,因爲不正確的「空」,所以他不看使用您的模板作爲候選人的函數調用的能力。

相關問題