《C++》模板详解
文章目录
- 一、模板定义及作用
- 二、函数模板
- 2.1语法解释
- 2.2显示实例化
- 2.3多个模板参数
- 2.4注意事项
- 三、类模板
- 3.1定义
- 3.2 类模板的实例化
- 3.3类模板的默认模板参数
一、模板定义及作用
- C++模板是一种允许编写与数据类型无关的通用代码的编程机制,它通过在编译时进行代码生成来实现泛型编程。
- C++模板的核心价值在于实现类型无关的通用代码,比如当你需要编写一个适用于任何数据类型的
max()
函数时,不必为int
、float
、string
等类型重复编写多份相同逻辑的代码,只需定义一个模板函数template <typename T> T max(T a, T b)
,编译器会自动为每种用到的类型生成特化版本,既避免了代码冗余,又保证了类型安全——就像用同一把模具(模板)铸造出不同材质的零件(具体实现),大幅提升了代码的复用性和可维护性
二、函数模板
2.1语法解释
- 函数模板是C++中实现泛型编程的基础工具,它允许我们编写独立于具体类型的通用函数。
template <typename T> // 或者 template <class T>
返回类型 函数名(参数列表) {// 函数体
}
示例:
template <typename T>
void Swap(T& a, T& b) {T temp = a;a = b;b = temp;
}int main()
{
int a = 5, b = 10;
swap(a, b); // 编译器生成swap<int>版本return 0;
}
- 这里提一嘴,交换函数在C++可以直接使用,其名字为
swap
,故我们这里将其大写化避免重构。
2.2显示实例化
- 显式实例化是C++模板编程中控制代码生成的重要机制,它允许开发者明确指定编译器在何时何地生成模板的特定类型实例。
- 这常常用来处理数据类型冲突的时候。
// 函数模板显式实例化
template 返回类型 函数名<具体类型>(参数列表);
示例
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main(void)
{int a = 10;float b = 20.0;// 显式实例化int ret = Add<int>(a, b);//这里冲突了,那么就按int来进行处理cout << fixed << ret << endl;//输出30return 0;
}
2.3多个模板参数
- 同样的,我们定义多个模板参数,示例如下:
template<class T1, class T2>
T2 Add(const T1& left, const T2& right)
{return left + right;
}
int main(void)
{int a = 10;float b = 20.0f;// 显式实例化float ret = Add(a, b);cout << fixed << ret << endl;//由于ret的类型是T2,T2匹配到的类型为float//故输出30.000000return 0;
}
2.4注意事项
-
模板定义通常需要放在头文件中
-
模板代码只有在被实例化时才会进行完整编译检查
-
错误信息可能较为复杂难懂
-
过度使用可能导致代码膨胀(编译生成多个实例)
三、类模板
3.1定义
- 类模板是 C++ 中用于定义泛型类的机制,允许类成员(如数据成员、成员函数)使用参数化类型,从而让同一个类可以适用于不同的数据类型。
- 其基本语法为:
template <typename T> // 或 template <class T>
class ClassName {
public:T memberVar; // 泛型成员变量ClassName(T val) : memberVar(val) {} // 构造函数void print() {cout << memberVar << endl;}
};
-
template (或 template )声明这是一个类模板,T 是模板类型参数。
-
T 可以是任意类型。
3.2 类模板的实例化
- 类模板本身并不是一个完整的类,必须显式或隐式实例化才能使用,而实例化的结果才是真正的类。。
- 类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可。
int main() {// 显式实例化(指定 T 为 int)ClassName<int> obj1(10);obj1.print(); // 输出 10// 显式实例化(指定 T 为 string)ClassName<std::string> obj2("Hello");obj2.print(); // 输出 Helloreturn 0;
}
3.3类模板的默认模板参数
- 类似的,我们依旧可以为类模板提供默认参数:
template <typename T = int> // 默认 T 是 int
class Box {
public:T content;Box(T val) : content(val) {}
};int main() {Box<> box1(10); // 使用默认 intBox<std::string> box2("ABC"); // 显式指定 stringreturn 0;
}