C++ 模板特化可讓我們為特定類型提供定制實作。依據特化參數形式,可分為三大類型:完全特化、偏特化(指標/引用)、偏特化(模板模板參數)。
template <class T>
class Compare {
public:
static bool IsEqual(const T& lhs, const T& rhs) {
return lhs == rhs;
}
};
針對具體類型提供專屬實作,模板參數列為空 template <>。
// 浮點數比較需容許誤差
template <>
class Compare<float> {
public:
static bool IsEqual(const float& lhs, const float& rhs) {
return std::abs(lhs - rhs) < 1e-3f;
}
};
template <>
class Compare<double> {
public:
static bool IsEqual(const double& lhs, const double& rhs) {
return std::abs(lhs - rhs) < 1e-6;
}
};
對類型施加結構性約束(如指標、引用、const),保留模板參數,不完全具體化。
// 指標特化:解引用後委託給元素類型的比較器
template <class T>
class Compare<T*> {
public:
static bool IsEqual(const T* lhs, const T* rhs) {
return Compare<T>::IsEqual(*lhs, *rhs);
}
};
// 同理可特化:const T*、T&、const T& 等
優勢:一次特化覆蓋 int*, float*, MyClass* 等所有指標類型,避免重複程式碼。
將模板參數限定為另一個模板實例,如 STL 容器、自訂模板類。
// vector 偏特化:逐元素比較
template <class T>
class Compare<std::vector<T>> {
public:
static bool IsEqual(const std::vector<T>& lhs, const std::vector<T>& rhs) {
if (lhs.size() != rhs.size()) return false;
for (size_t i = 0; i < lhs.size(); ++i)
if (lhs[i] != rhs[i]) return false;
return true;
}
};
// 自訂模板類偏特化
template <class T1>
struct SpecializedType { T1 x1, x2; };
template <class T>
class Compare<SpecializedType<T>> {
public:
static bool IsEqual(const SpecializedType<T>& lhs, const SpecializedType<T>& rhs) {
return Compare<T>::IsEqual(lhs.x1 + lhs.x2, rhs.x1 + rhs.x2);
}
};
Compare<int>::IsEqual(10, 10); // 通用版
Compare<float>::IsEqual(1.0f, 1.001f); // 完全特化
Compare<int*>::IsEqual(&a, &b); // 指標偏特化
Compare<std::vector<int>>::IsEqual(v1, v2); // 模板偏特化
Compare<SpecializedType<float>>::IsEqual(s1, s2); // 自訂模板偏特化
| 類型 | 語法特徵 | 適用場景 |
|---|---|---|
| 完全特化 | template <> Class<ConcreteType> | 特定類型需完全不同行為 |
| 指標/引用偏特化 | template <class T> Class<T*> | 統一處理所有指標/引用類型 |
| 模板偏特化 | template <class T> Class<OtherTemplate<T>> | 統一處理某類模板實例化類型 |
善用三類特化,能構建極具彈性與效能的泛型程式庫。