2012-01-05 20 views
0

我想在C++中學習模板。有人可以解釋爲什麼sq()工作和add()不是? add()如何修復?什麼是非類型模板的使用?如何在C++中創建和使用非類型模板以及將在何處使用

template <typename T> 
inline T sq (const T& x) 
{ 
    return x*x; 
} 

template <int*> 
inline int add(int* x) 
{ 
    return (*x)*2; 
} 



int main() { 
int x = 2; 
cout<<"Square(2): "<<sq(2)<<" Add(2): "<<add(&x)<<endl; 
return 0; 
} 

即使修改如下上面的例子之後,也仍然無法正常工作

template <typename T> 
inline T sq (const T& x) 
{ 
    return x*x; 
} 

template <int> 
inline int add(int x) 
{ 
    return x+x; 
} 



int main() { 
    cout<<"Square(2): "<<sq(2)<<" Add(2): "<<add(2)<<endl; 
    return 0; 
} 
+0

添加的確切目的並不重要,正如我上面提到的,它只是爲了學習。事實是,添加從語法角度來看是有效的。我的問題是如何使用它,爲什麼簡單的添加(&x)不起作用? – Jimm 2012-01-05 16:27:32

+0

在這種情況下,添加(X)_would_工作,這就是爲什麼人們感到困惑, – 2012-01-05 16:46:19

回答

4

我不太清楚你問什麼,但你可以使用一個非類型模板參數,例如,定義一個函數模板,增加了任何編譯時間常數它的參數:

template <int N> 
inline int add(int x) 
{ 
    return x + N; 
} 

int main() 
{ 
    std::cout << add<3>(2) << std::endl; // prints 5 
    std::cout << add<4>(2) << std::endl; // prints 6 
} 

要回答你關於爲什麼sq(2)編譯但add(&x)沒有按」具體問題t:輸入參數可以從函數參數中推導出函數模板的參數。所以sq(2)相當於sq<int>(2)。非類型參數不能被推斷,所以你必須提供一個參數。在一個指針參數的情況下,該參數必須是指向具有外部鏈接的變量,所以下面應編譯:

int global; 

int main() { 
    int local = 2; 
    std::cout << add<&global>(&local) << std::endl; 
} 
+0

據我所知,無論是int和指針是「非類型」參數。但是對於sq(2),編譯器能夠從參數中推斷出來,但不能用於指針。你可以聲明添加爲模板內嵌INT加(INT X){....},它仍然不會作爲添加工作(2) – Jimm 2012-01-05 17:13:56

+1

@Jimm:'sq'有一個類型參數('typename的T');從函數參數中減去該參數的類型'int'。 'add'有一個非類型參數('int *'),其值不能被推斷出來。 – 2012-01-05 17:19:47

+0

在我的修改示例中,添加的模板只能用於int。語法模板將選擇限制爲接受int類型的參數。因此,有沒有離開的情況下在這個實例的情況下扣除.... – Jimm 2012-01-05 17:28:57

2

add函數不使用任何模板相關的功能。它可以很好地作爲非模板函數。我無法弄清楚你真的想做什麼,所以不幸的是,我甚至無法猜測你的真正問題。

編輯:如果您的頭銜,我推斷你想了解非類型模板參數,那是完全不完整的數組例如:

template <typename T, int length> 
struct Array 
{ 
    T array_data_[length]; 
}; 
4

使用非類型模板參數用於 功能模板的典型例子會是這樣的:

template <typename T, size_t N> 
T* 
end(T (&array)[N]) 
{ 
    return array + N; 
} 

在這種情況下,如果你寫的東西,如:

int a[] = { 1, 2, 3, 4 }; 
int* endPtr = end(a); 

,編譯器可以推斷的長度陣列爲你。

+0

爲結束時的語法(T(&陣列)[N] )很奇怪。用於數組參數正常功能,我會簡單地寫爲端(int數組[]),然後將模板等效應端(T常用3 []) – Jimm 2012-01-05 20:27:56

+2

@Jimm於C樣式數組傳遞給函數的唯一方法是通過參考(如上)。 'end(T array [N])'和'end(T * array)'是一樣的,它不會給出任何參數推導來確定實際長度的方法(並且在傳遞指針時不會給出錯誤) 。 – 2012-01-06 08:43:43

-1

正如有人說,你正在嘗試做的是一些毫無意義如何,當你可能需要提供模板的確切參數類型的唯一情況是模板函數重載。例如,當你想讓一些函數以某種特殊類型的不同方式工作時,這被稱爲模板特化。欲瞭解更多詳細信息,你可能想要訪問 : Function template specialization format

+0

聽起來像你正在考慮模板類型的模板專業化。問題是關於非類型模板_parameters_。 – 2012-01-05 16:49:05

+0

好的是,這個問題是關於非類型參數,但是我指的是一塊代碼,它是直接定義數據類型的模板組合,對於我來說聽起來像模板專業化,因爲'我試圖在C++中學習模板。 '我認爲這可能是有用的 – user989583 2012-01-05 17:19:41

+0

對於模板專業化,它將是'template <> inline int add (int * x)'這是不同的。此代碼不是專業化的。 – 2012-01-05 18:57:00

-1

模板的一點是,那麼你沒有定義的函數或類特定的數據類型。 看看T add (const T& x)。這裏沒有數據類型,只是一個大的T。這是由於模板可以假定任何數據類型的標識,即int,double,char或任何您所投射的數據類型。

#include <iostream> 
using namespace std; 

template <typename T> 
inline T sq (const T& x) 
{ 
    return x*x; 
} 

template <typename T> 
inline T add (const T& x) 
{ 
    return x+x; 
} 

template <typename T> 
inline T divide (const T& x, const T& y) 
{ 
    return x/y; 
} 


int main() 
{ 
    int x = 3; 
    cout<<"int \n"; 
    cout<<"Square(3) : "<<sq(x)<<" \n"; 
    cout<<"Add(3)  : "<<add(x)<<" \n"; 

    double y=3.00; 
    cout<<"\ndouble \n"; 
    cout<<"Square(3) : "<<sq(y)<<" \n"; 
    cout<<"Add(3)  : "<<add(y)<<" \n"; 

    double v=3.00; 
    double w=2.00; 
    cout<<"\ndouble \n"; 
    cout<<"Square(3) : "<<sq(v)<<" \n"; 
    cout<<"Add(3)  : "<<add(v)<<" \n"; 
    cout<<"divide(3/2) : "<<divide(v,w)<<" \n"; 
    cout<<"\n \n"; 

return 0; 
} 
+1

還有非類型的模板參數,用於其他目的。 – 2012-01-05 17:10:36

相關問題