1.代碼展示
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
//函數模板
int add(int x, int y)
{
return x + y;
}
template<typename T>
T add(const T& x,const T& y)
{
return x + y;
}
void test1()
{
int ret = 0;
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
//ret = add(a1, a2);//存在非模板函數直接調用非函數模板。
//ret = add(d1, d2); //不存在非函數模板,隱式實例化,根據參數自己匹配。
//ret = add(a1, d2);//參數類型不統一時,不能調用函數模板,調用非函數模板。
//ret = add((double)a1, d2);//強轉->函數模板,而非函數模板可以自己轉化
//ret = add<int>(a1, d2);//顯示實例化->函數模板
cout << ret << endl;
}
#include<string>
//類模板
namespace xff
{
template<class T>
class vector
{
public:
vector(const T& val = T())
{
_val = val;
cout <<"T->" <<_val << endl;
}
~vector()
{
}
private:
T _val;
};
template<class T>//類外定義時要加模板參數列表
vector<T>::~vector()
{
}
}
void test2()
{
xff::vector<int> v1(10);
xff::vector<string> v2("hello");
}
int main()
{
//test1();
//test2();
system("pause");
return 0;
}
2.函數模板
函數模板和函數重載都是爲了實現泛型編程,而函數重載不能根本解決問題,還是有代碼冗餘,所以引入函數模板來實現,通過編譯器根據類型匹配特化出對應的版本,是一種靜態多態,也成爲編譯時多態。
通過上面的例子,我們可以看到,如果我們自己定義了函數,那麼我們傳入的參數匹配的話,會直接調用這個參數,如果類型不匹配,會默認實現類型轉化,所以會丟失精度。但是,如果我們寫了函數模板,那麼編譯器會根據參數來匹配,優先匹配非函數模板。如果類型不匹配,可以通過顯示實例化或者類型強轉實現函數模板匹配。
總之,通過函數模板,可以特化出我們需要的一致參數類型,不一致參考上面的理解。
3.類模板
類模板也是爲了解決泛型編程的問題,例如我們實現vector容器時,如果我們顯示定義了容器內的數據類型,那麼其他數據類型,又需要重新寫一份代碼了,所以爲了避免冗餘,實現代碼複用,所以引入類模板,通過類模板,我們顯示實例化出類型,然後匹配。
例如我們實現vector中存放string,或者存放int,當然我們代碼實現的過程就要考慮的更多了,例如string類型可能會出現淺拷貝問題,其他容器也可能會有大小比較等等,一系列問題,所以要提高自己的代碼能力。