目录
一、模板概述
C++模板是一种强大的语言特性,用于实现泛型编程。它允许程序员定义通用的函数和类,这些函数和类可以使用任意类型作为参数,从而提高代码的复用性和灵活性。模板分为函数模板和类模板两种类型。
二、模板实例
#include <iostream>
using namespace std;
// 函数主模板
template <typename T>
void print(T value)
{
cout << "General template: " << value << endl;
}
// 函数模板的全特化
template <>
void print<int>(int value)
{
cout << "Specialized for int: " << value << endl;
}
// 类主模板
template <typename T, typename U>
class Pair
{
public:
T first;
U second;
Pair(T t, U u) : first(t), second(u) { cout << "General Pair" << endl; }
};
// 类模板的偏特化
template <typename U>
class Pair<int, U>
{
public:
int first;
U second;
Pair(int t, U u) : first(t), second(u) { cout << "Partial specialization for int, U" << endl; }
};
// 类模板的偏特化
template <typename T>
class Pair<T, double>
{
public:
T first;
double second;
Pair(T t, double u) : first(t), second(u) { cout << "Partial specialization for T, double" << endl; }
};
// 类模板的全特化
template <>
class Pair<char, int>
{
public:
char first;
int second;
Pair(char t, int u) : first(t), second(u) { cout << "specialization for char, int" << endl; }
};
int main()
{
print(10); // 调用函数全特化版本
print(3.14); // 调用函数通用模板版本
Pair<char, int> charIntPair('a', 2); // 调用类全特化版本
Pair<char, double> charDoublePair('a', 3.14); // 调用类偏特化版本
Pair<int, double> intDoublePair(1, 2.71); // 调用类偏特化版本
Pair<int, char> intCharPair(1, 'b'); // 调用类通用模板版本
return 0;
}
输出结果
Specialized for int: 10
General template: 3.14
specialization for char, int
Partial specialization for T, double
Partial specialization for int, u
General Pair
二、函数模板
(一)定义与实例化
函数模板是一种通用函数的定义方式,它允许函数操作的数据类型作为参数传递。函数模板的定义格式如下:
template <typename T>
返回类型 函数名(参数列表)
{
// 函数体
}
在调用函数模板时,模板参数类型可以由编译器自动推断,也可以显式指定。
示例代码
template <typename T>
void print(T value)
{
cout << value << endl;
}
int main()
{
print(10); // 实例化为 print<int>
print(3.14); // 实例化为 print<double>
}
(二)模板参数的显式指定
在调用函数模板时,可以显式指定模板参数的类型:
print(10); // 实例化为 print<int>
print(3.14); // 实例化为 print<double>
(三)模板参数的默认值
函数模板的模板参数可以有默认值:
template <typename T = int>
void print(T value)
{
cout << value << endl;
}
(四)模板特化
模板特化是指为特定的模板参数类型提供一个特殊的实现。函数模板不支持偏特化,但可以通过全特化或重载来实现类似的功能。
1. 全特化
全特化是指为模板的所有模板参数提供特定的类型实现。
// 原始版本
template <typename T>
void print(T value)
{
cout << "General template: " << value << endl;
}
// 特化版本
template <>
void print<int>(int value)
{
cout << "Specialized for int: " << value << endl;
}
2. 偏特化
实际上,函数模板不支持偏特化,但可以通过全特化或重载来实现类似的功能。
template <typename T>
void print(T value)
{
cout << "General template: " << value << endl;
}
void print(int value)
{
cout << "overriding: " << value << endl;
}
三、类模板
(一)定义与实例化
类模板是一种通用类的定义方式,它允许类的成员变量和成员函数操作的数据类型作为参数传递。类模板的定义格式如下:
template <typename T>
class 类名
{
// 类的成员变量和成员函数
};
在实例化类模板时,需要为模板参数指定具体的类型。
示例代码
#include <iostream>
using namespace std;
template <typename T>
class Stack
{
private:
T data[100];
int top;
public:
Stack() : top(-1) {}
~Stack() {}
};
int main()
{
Stack<int> intStack;
Stack<double> doubleStack;
return 0;
}
Stack<int> 和Stack<double> 实例化 Stack 类模板生成的具体类
(二)模板参数的显式指定
在实例化类模板时,可以显式指定模板参数的类型:
Stack<int> intStack; // 显式指定模板参数类型为 int
Stack<double> doubleStack; // 显式指定模板参数类型为 double
(三)模板参数的默认值
类模板的模板参数可以有默认值:
template <typename T = int>
class Stack
{
// 类的成员变量和成员函数
};
(四)模板特化
模板特化是指为特定的模板参数类型提供一个特殊的实现。特化分为全特化和偏特化,其中将模板参数全部写死为全特化,即固定了具体类型;而偏特化后的模板参数表里仍然存在可变的部分。假设只有一个参数,参数类型为int*属于全特化,参数类型T*是偏特化。
1. 全特化
全特化是指为模板的所有模板参数提供特定的类型实现。
// 原始模板
template <typename T>
class Stack
{
public:
void push(T value) { cout << "General push: " << value << endl; }
};
// 全特化
template <>
class Stack<int>
{
public:
void push(int value) { cout << "Specialized push for int: " << value << endl; }
};
2. 偏特化
偏特化是指为模板的部分模板参数提供特定的类型实现,而其他模板参数仍然保持通用。偏特化只能用于类模板。
// 1. 原始模板(主模板)
template<typename T, typename U>
class Pair { /* 通用实现 */ };
// 2. 偏特化:固定第一个参数为 int
template<typename U>
class Pair<int, U> { /* 针对 int 的优化 */ };
// 3. 偏特化:两个参数都是指针
template<typename T, typename U>
class Pair<T*, U*> { /* 指针特化 */ };
// 4. 偏特化:第二个参数是数组
template<typename T, size_t N>
class Pair<T, T[N]> { /* 数组特化 */ };
四、全特化与偏特化的区别
(一)作用对象
全特化:可以应用于函数模板和类模板。
偏特化:只能应用于类模板。
(二)模板参数
全特化:所有模板参数都被指定为具体类型。
偏特化:部分模板参数被指定为特定类型,其他模板参数仍然保持通用。
(三)实例化优先级
当存在全特化、偏特化和通用模板时,优先级顺序为:
全特化 > 偏特化 > 通用模板
五、模板的优缺点
(一)优点
代码复用性高:模板允许定义通用的函数和类,可以用于任意类型的数据,减少了代码冗余。
类型安全:模板在编译时会进行类型检查,确保模板参数类型与函数或类的使用方式一致,避免了类型错误。
性能优化:模板在编译时生成特定类型的代码,避免了运行时的类型转换和动态绑定,提高了程序的运行效率。
(二)缺点
编译时间增加:模板的使用会导致编译器生成大量的模板实例代码,增加了编译时间。
代码膨胀:模板实例化会生成多个版本的代码,可能导致代码体积增大。
调试困难:模板错误的诊断和调试相对复杂,因为编译器生成的模板实例代码可能难以理解。
六、总结
| 维度 | 主模板 | 偏特化 | 全特化 |
|---|---|---|---|
| 模板参数 | 全部泛型 | 部分固定 | 全部固定 |
| 适用对象 | 类模板/函数模板 | 仅类模板 | 类模板/函数模板 |
| 语法 | template<typename T, typename U> | template<typename U> | template<> |
| 优先级 | 最低 | 中 | 最高 |
C++模板是一种强大的语言特性,用于实现泛型编程。通过模板,可以定义通用的函数和类,提高代码的复用性和灵活性。函数模板和类模板的使用方式类似,都支持模板参数的显式指定、默认值和特化。模板特化分为全特化和偏特化两种类型,全特化可以应用于函数模板和类模板,而偏特化只能应用于类模板。合理使用模板可以提高代码的可维护性和可扩展性。
11万+

被折叠的 条评论
为什么被折叠?



