2011-08-25 84 views
1
#include <iostream> 
#include <vector> 
using namespace std; 

template <typename nameOfTheVariableTypeA, 
     typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX 
               (nameOfTheVariableTypeA argA, 
               (nameOfTheVariableTypeB argB) 
{ 
    nameOfTheVariableTypeA tempArgA; 
    nameOfTheVariableTypeB tempArgB; 

    argA.push_back(22); 

    tempArgA = argA; 
    cout << "\ntempArgA: " << tempArgA[0] << "\n"; 

    tempArgB = argB; 
    cout << "\ntempArgB: " << tempArgB << "\n"; 

    return tempArgB; 
} 

int main() 
{ 
    functionX (12, 12.4567); 

    vector <int> f; 
    functionX (f, 12.4567); 

    return 0; 
} 

從模板書: An attempt to instantiate a template for a type that doesn't support all the operations used within it will result in a compile-time error.實例化一個模板矢量

我爲上述代碼接收到的錯誤是:

  1. error: request for member ‘push_back’ in ‘argA’, which is of non-class type ‘int’

  2. error: subscripted value is neither array nor pointer

我錯過了什麼觀點?

+0

也許代碼不應該編譯?這可能僅僅是本書正在討論的內容的一個示範。 –

+0

@In silico不,那個代碼是「我的」,我想了解錯誤的原因。 –

回答

3

首先,有一個多餘的括號:

template <typename nameOfTheVariableTypeA, 
     typename nameOfTheVariableTypeB> nameOfTheVariableTypeB functionX 
               (nameOfTheVariableTypeA argA, 
               /*(*/nameOfTheVariableTypeB argB) 
// Note: extra parenthesis not needed here -----^ 
{ 

假設這只是一個錯字,讓我們來看看在第一次調用functionX()

現在
functionX(12, 12.4567); 

,模板功能要求所有的模板在調用它們之前指定參數。但在某些情況下,編譯器可以推斷出函數調用工作所需的類型爲nameOfTheVariableTypeAnameOfTheVariableTypeB

在這種情況下,12是一個整數字面值,因此它的類型爲int12.4567是一個浮點文字,因此它的類型爲double。因此,在functionX(),nameOfTheVariableTypeAint類型和nameOfTheVariableTypeB類型是double

既然已經指定了所有的模板參數(在這種情況下推導出來),編譯器可以實例化模板函數。也就是說,編譯器創建一個函數,它看起來像這樣:

// Hypothetical function generated by the compiler 
double functionX_int_double(int argA, double argB) 
{ 
    int tempArgA; 
    double tempArgB; 
    // ... 

就好像編譯器簡單地取代nameOfTheVariableTypeAnameOfTheVariableTypeB與推測的類型。顯然,參數argA和變量tempArgA的類型爲int。您會得到第一個錯誤,因爲int沒有名爲push_back()的類成員函數。這是同樣的原因,這是行不通的:

int i = 20; 
i.push_back(22); 

您還可以得到,因爲下標運算符[]int s沒有定義的第二個錯誤。再次,這是同樣的原因,這是行不通的:

int j = 21; 
cout << j[0]; 

注意,這種信息可以從編譯器錯誤自行收集。確保你閱讀它們!

+2

+1:我沒有看到額外的paren,也許是因爲不必要的長類型名稱... –

+0

@Rene放置解釋性變量名是一種有益的做法。 –

+3

@Anisha Kaul:不言自明的名字很好,但不要與他們搭訕。 :-)簡潔;例如'TypeA'和'TypeB'就像描述性一樣,但需要更少的努力來輸入。 –

1

呼叫

functionX (12, 12.4567); 

instantiantes與(int, double)參數的函數。 int argA既沒有push_back()方法也沒有數組索引運算符。所以你也不能使用tempArgA[0]

1

在你第一次調用functionX

functionX (12, 12.4567); 

類型nameOfTheVariableTypeA模板內會被推斷爲int。顯然int類型不支持push_back()operator[]

1

你的模板專業化的完整代碼:)。正如其他人所說,「int」沒有push_back函數,因此您需要專門的實現。

 
template < typename nameOfTheVariableTypeA, 
     typename nameOfTheVariableTypeB > 
nameOfTheVariableTypeB functionX (nameOfTheVariableTypeA argA,nameOfTheVariableTypeB argB) 
{ 
    nameOfTheVariableTypeA tempArgA; 
    nameOfTheVariableTypeB tempArgB; 

    argA.push_back(22); 

    tempArgA = argA; 
    cout << "\ntempArgA: " << tempArgA[0] << "\n"; 

    /*tempArgB = argB; 
    cout << "\ntempArgB: " << tempArgB << "\n";*/ 

    return tempArgB; 
} 
template < > 
float functionX < int,float > (int argA,float argB){ 

     int tempArgA; 
    int tempArgB; 

     tempArgA = argA; 
    cout << "\ntempArgA: " << tempArgA << "\n"; 

     return tempArgB; 
} 


int main() 
{ 
    functionX < int,float >(12, 12.4567); 

    vector < int > f; 
    functionX < vector < int > , float > (f, 12.4567); 

    return 0; 
}