模板实例化有两种,一种是通用模板实例化,还有一种是特例化模板。通用模板实例化没啥好说的,这里详细说一下特例化模板。
在C++中,模板通常被设计为通用的,以便在多个类型或参数上工作。然而,有时你希望为特定类型或特定参数组合提供专门的实现,这时就需要用到特例化模板(Template Specialization)。
C++中的特例化模板可以分为两种类型:
- 全特例化(Full Specialization):为某个模板提供针对特定类型或特定参数的完全实现。
- 偏特例化(Partial Specialization):为某个模板的某些参数提供特定实现,而其他参数仍然是通用的。
直接看代码就好了
template<typename T>
class MyClass {
public:
void display() {
std::cout << "Generic template" << std::endl;
}
};
// 全特例化
template<>
class MyClass<int> {
public:
void display() {
std::cout << "Specialized template for int" << std::endl;
}
};
int main() {
MyClass<double> obj1;
obj1.display(); // 输出: Generic template
MyClass<int> obj2;
obj2.display(); // 输出: Specialized template for int
return 0;
}
template<typename T, typename U>
class MyClass {
public:
void display() {
std::cout << "Generic template" << std::endl;
}
};
// 偏特例化
template<typename T>
class MyClass<T, int> {
public:
void display() {
std::cout << "Partial specialization where second type is int" << std::endl;
}
};
int main() {
MyClass<double, double> obj1;
obj1.display(); // 输出: Generic template
MyClass<double, int> obj2;
obj2.display(); // 输出: Partial specialization where second type is int
return 0;
}
注意:在C++中,不需要在编写全特例化或偏特例化之前写一个通用模板实例化。可以直接编写全特例化或偏特例化而不需要先定义通用版本。不过,通常会有一个通用的模板版本,以便为没有特例化的参数组合提供默认的实现。(尖括号里面一般是模板参数)
// 通用实例化
template<typename T>
class MyClass {
public:
void display() {
std::cout << "Generic template" << std::endl;
}
};
// 直接写全特例化
template<>
class MyClass<int> {
public:
void display() {
std::cout << "Specialized template for int" << std::endl;
}
};
// 这种情况下,没有通用版本,只能使用int类型
int main() {
MyClass<int> obj;
obj.display(); // 输出: Specialized template for int
// MyClass<double> obj2; // 错误:因为没有定义通用模板或double类型的特例化版本
return 0;
}
// 直接写偏特例化
template<typename T>
class MyClass<T, int> {
public:
void display() {
std::cout << "Partial specialization where second type is int" << std::endl;
}
};
// 这种情况下,没有通用版本,只能使用T和int类型作为第二参数的组合
int main() {
MyClass<double, int> obj;
obj.display(); // 输出: Partial specialization where second type is int
// MyClass<double, double> obj2; // 错误:因为没有定义通用模板或double, double组合的特例化版本
return 0;
}
就这样。