[c++中模板的特化](https://blog.csdn.net/M_jianjianjiao/article/details/85220983)
[C++ 模板 全特化與偏特化](https://mp.weixin.qq.com/s/H1yxh6IUtplzY7EHFQmwzQ)
[C++ 模板特化與偏特化](https://mp.weixin.qq.com/s/kbXxSg1euk9r6x0uxdkVkw)
*****
## C++ 模板 全特化與偏特化
> 模板
**模板定義:模板就是實現代碼重用機制的一種工具,它可以實現類型參數化,即把類型定義為參數, 從而實現了真正的代碼可重用性。模版可以分為兩類,一個是函數模版,另外一個是類模版。**
大白話:C++是一門強類型語言,編寫一段通用的邏輯,可以把任意類型的變量傳進去處理,通過把通用邏輯設計為模板,擺脫了類型的限制,極大地提升了代碼的可重用性。
\*\*模板實例化:\*\*模板定義本身不參與編譯,而是編譯器根據模板的用戶使用模板時提供的類型參數生成代碼,再進 行編譯。用戶提供不同的類型參數,就會實例化出不同的代碼。
* * *
> 類模板
**類模板**描述了一組相關的類或數據類型,它們只能通過類型來區分:整數值、指向(或引用)具有全局鏈接的變量的指針、其他的組合。類模板尤其適用于描述通用但類型安全的數據結構。
類模板使用:
~~~
template?<類型形式參數>????class?類名??
?{??
???//類聲明體;????
};???????
?template?<類型形式參數>????返回類型?類名?<類型>?::?成員函數名1(形式參數)???
?{???
??//成員函數定義體;????
}???
?...?...???
?template?<類型形式參數>????返回類型?類名?<類型>?::?函數名N(形式參數)???
?{??
//成員函數定義體;???
?}
~~~
案例:
~~~
#include?<iostream>
using?namespace?std;
template<class?T>class?Compare
{
public:?
bool?equal(T?a,T?b);
};
template<class?T>bool?Compare<T>::equal(T?a,?T?b)
{?
return?a?==?b;
}
int?main(){?
Compare<int>C;?C.equal(1,2);?
return?0;
}
~~~
* * *
> 類模板全特化
所謂模板全特化限定死模板實現的具體類型;
比如上述這個例子,我們比較int類型這種還可以,但是比較float這種類型就不行,這時候就需要進行模板特化;
~~~
#include <iostream>
using namespace std;
template<class T>
class Compare
{
public:
bool equal(T a, T b);
};
template<class T>
bool Compare<T>::equal(T a, T b)
{
return a == b;
}
//模板全特化
template<>
class Compare<float>
{
public:
bool equal(float a, float b);
};
bool Compare<float>::equal(float a, float b)
{
return std::abs(a - b) < 10e-3;
}
int main()
{
Compare<int>C;
cout << C.equal(1, 2) << endl;
Compare<float>C2;
cout << C2.equal(1.001, 1.001) << endl;
return 0;
}
~~~
* * *
> 類模板偏特化
偏特化是指提供另一份template定義式,而其本身仍為`templatized`,這是針對于`template`參數更進一步的條件限制所設計出來的一個特化版本。也就是如果這個模板有多個類型,那么**只限定其中的一部分**;
~~~
#include <iostream>
using namespace std;
template<class T1, class T2>
class Test
{
public:
Test(T1 a, T2 b) :_a(a), _b(b)
{
cout << "模板化" << endl;
}
private:
T1 _a;
T2 _b;
};
//模板全特化
template<>
class Test<int, int>
{
public:
Test(int a, int b) :_a(a), _b(b)
{
cout << "模板全特化" << endl;
}
private:
int _a;
int _b;
};
//模板偏特化
template<class T>
class Test<int, T>
{
public:
Test(int a, T b) :_a(a), _b(b)
{
cout << "模板偏特化" << endl;
}
private:
int _a;
T _b;
};
int main()
{
Test<double, double> t1(1.01, 1.01);
Test<int, int> t2(1, 1);
Test<int, char*> t3(1, "111");
return 0;
}
~~~
* * *
> 函數模板
函數模板一般定義:
~~~
template <類型形式參數>
//類型形式參數即此格式:<typename 形式參數> 或 <class 形式參數>
返回類型 函數名 (形式參數)
{
//函數定義體;
}
~~~
案例:
~~~
#include <iostream>
using namespace std;
//普通模板
template<class T1, class T2>
bool Compare(T1 a, T2 b)
{
return a == b;
}
int main()
{
cout << Compare(1, 2) << endl;
return 0;
}
~~~
* * *
> 函數模板特化
函數模板特化和類模板特化本質是一樣的,是對模板參數的特殊化處理:
~~~
#include <iostream>
using namespace std;
//普通模板
template<class T1, class T2>
bool Compare(T1 a, T2 b)
{
cout << "普通模板" << endl;
return a == b;
}
//函數模板特化
template<>
bool Compare(const char* a, const char* b)
{
cout << "函數模板特化" << endl;
return strcmp(a, b) == 0;
}
int main()
{
cout << Compare(1, 2) << endl;
cout << Compare("ab", "ab") << endl;
return 0;
}
~~~
* * *
> 總結
1、函數模板只有特化,沒有偏特化;
2、模板、模板的特化和模板的偏特化都存在的情況下,編譯器在編譯階段進行匹配,優先特殊的;
3、模板函數不能是虛函數;因為每個包含虛函數的類具有一個virtual table,包含該類的所有虛函數的地址,因此vtable的大小是確定的。模板只有被使用時才會被實例化,將其聲明為虛函數會使vtable的大小不確定。所以,成員函數模板不能為虛函數。
- C++基礎
- 什么是 POD 數據類型?
- 面向對象三大特性五大原則
- 低耦合高內聚
- C++類型轉換
- c++仿函數
- C++仿函數了解一下?
- C++對象內存模型
- C++11新特性
- 智能指針
- 動手實現C++的智能指針
- C++ 智能指針 shared_ptr 詳解與示例
- 現代 C++:一文讀懂智能指針
- Lamda
- c++11多線程
- std::thread
- std::async
- std::promise
- std::future
- C++11 的內存模型
- 初始化列表
- std::bind
- std::tuple
- auto自動類型推導
- 可變參數模板
- 右值引用與移動語義
- 完美轉發
- 基于范圍的for循環
- C++11之POD類型
- std::enable_if
- C++14/17
- C++20
- 協成
- 模塊
- Ranges
- Boost
- boost::circular_buffer
- 使用Boost.Asio編寫通信程序
- Boost.Asio C++ 網絡編程
- 模板
- 模板特化/偏特化
- C++模板、類模板、函數模板詳解都在這里了
- 泛化之美--C++11可變模版參數的妙用
- 模板元編程
- 這是我見過最好的模板元編程文章!