C++ 模板机制详解:参数、特化与分离编译
前言
泛型编程是 C++ 的核心特性之一,而模板(Template)则是实现泛型的关键。本文将深入探讨模板参数的分类、模板特化的具体用法,以及在实际工程中常遇到的分离编译问题及其解决方案。
模板参数
模板允许我们在编写代码时使用参数化的类型或值,从而实现代码复用。C++ 的模板参数主要分为三类:类型参数、非类型参数和模板模板参数。
一、类型参数
类型参数表示模板中使用的数据类型可以是内置类型(如 int、double)或自定义类型(如类、结构体)。
1. 通用与默认类型参数
我们可以为类型参数指定默认值,调用时若未显式指定则使用默认值。
template<typename T = int> // 默认类型为 int
class Stack {
// ...
};
Stack<> s; // 使用默认类型 int
Stack<double> d; // 显式指定类型为 double
在函数调用中,编译器通常能自动推导类型,但也可以显式指定:
swap<int>(3, 5); // 显式指定类型为 int
swap<double>(3.14, 2.71); // 显式指定类型为 double
// 也可隐式推导:swap(3, 5);
声明类型参数时,class 和 typename 含义相同,推荐统一使用 typename 以增强可读性:
template<typename T>
void swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
二、非类型参数
非类型参数(Non-Type Parameters)用于传递常量值,通常为整型、枚举值或指针/引用。C++11 后支持 std::nullptr_t 和 constexpr 变量等。
1. 基本语法与限制
对于指针或引用类型的非类型参数,要求指向的对象具有静态存储期(如全局变量、static 变量)。此外,非类型参数必须是编译期可确定的常量。
int global_var = ;
{ }
<&global_var>();
Array<, > arr;
n = ;


