什麼是模板:
模板是c++中泛型編程的基礎,一個模板就是一個創建類或函數的藍圖或者說是公式,當使用一個vector這樣的泛型類型或者find這樣的泛型函數時,我們提供足夠的信息,將藍圖轉換爲特定的類或者函數
函數模板:
定義模板:
假如我們要比較兩個數的大小,我們可能會寫出下面這樣的函數
//比較兩個string類參數大小
int compare(const string &v1, const string &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
//比較兩個double類型參數
int compare(const double &v1, const double &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
這時我們發現,除了類型不同,函數體基本完全相同,我們便引入了函數模板。
我們可以定義一個通用的函數模板,而不是爲每個類型都定義新函數。代碼如下:
template <typename T> //使用<class T> 效果完全一樣
int compare(const T &v1, const T &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
<>內表示模板參數列表 這是一個逗號分隔的多個模板參數的列表,在模板定義中參數列表不能爲空模板函數只是一個聲明,當調用模板時,編譯器會根據參數來實例化對應參數的函數來使用
調用模板函數:
float m = 1.5, n = 2.5;
double x = 10.5, y = 20.5;
int a = 1, b = 2;
//模板函數的調用 模板函數默認不作類型轉換
compare(m,n); //compare(float,float)
compare(x, y); //compare(double,double)
//compare(a, y); //error
模板函數的實例化:
當調用一個函數模板時,編譯器會利用給定的函數實參來推斷模板實參,用此實際實參代替模板參數來創建出模板的一個新的實例,也就是一個新函數,這個過程稱爲實例化。
其他細節:
模板函數爲了防止類型出錯,所以不會作自動類型轉換,比如int轉換爲float。
編譯器會根據函數的第一個參數來實例化對應類型的模板函數,所以當參數的類型不同時,編譯器會報錯。
例題:
編寫一個print函數模板,它接收一個數組的引用,能處理任意大小、任意元素類型的數組
template <typename T,size_t N>
void print(const T (&a)[N])
{
for (auto iter = begin(a); iter != end(a); iter++)
{
cout << *iter << "";
}
cout << endl;
}
int main()
{
int a[6] = { 0,1,2,3,4,5 };
print(a);
return 0;
}
類模板:
類模板的定義:
template <class T>
class Vector {
public:
Vector(int); //構造函數(int)
~Vector(); //析構
Vector(const Vector&); //拷貝構造函數
Vecotr& operator=(const Vector&); //=運算符重載
T& operator[](int); //[]運算符重載
private:
T* m_elements;
int m_size;
};
類模板的所有函數也是模板函數
類模板中函數的定義:
template <class T>
Vector<T>::Vector(int size) :m_size(size)
{
m_elements = new T[m_size];
}
template <class T>
T& Vector<T>::operator[](int index)
{
if (index <m_size &&index >0)
{
return m_elements[index];
}
else
{
...
}
}