一、函数模板
函数模板实现通用函数,根据传递类型进行编译时实参推导:
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
int x = 1, y = 2;
double m = 1.5, n = 2.5;
int z = add(x, y);
double p = add(m, n);
return 0;
}
这里template <typename T>
声明了一个泛型类型T,然后使用T作为add函数的参数和返回值类型。这使得add可以接受不同类型的a,b,并返回相应类型的和。编译器会根据传参类型实时实例化add。
二、类模板
类模板生成可以根据类型参数化的类:
template <typename T>
class Stack {
private:
T arr[100];
int top;
public:
void push(T);
T pop();
};
int main() {
Stack<int> s1;
Stack<double> s2;
s1.push(1);
s2.push(1.5);
return 0;
}
类模板的语法类似,template
后声明类型参数,然后在类中使用该类型参数,来定义可以通用的类。Stack类就可以因类型T的不同而实例化出Stack
三、模板特化
模板特化用于自定义某个类型的实现:
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
// 特化int的max实现
template <>
int max<int>(int a, int b) {
cout << "Int specialization";
return a > b ? a : b;
}
int main() {
int x = 1, y = 2;
double m = 1.5, n = 2.5;
max(x, y); //calls int specialization
max(m, n); //calls original
return 0;
}
这里使用template<>
的语法,为int类型的max定制了一个专属实现。这让我们不影响原模板的同时,可定制某些特定类型。
四、偏特化
偏特化用于定制模板的部分参数类型:
// 原类模板
template<typename T1, typename T2>
class Test {
public:
T1 value1;
T2 value2;
Test(T1 v1, T2 v2) {
value1 = v1;
value2 = v2;
}
};
// 偏特化版本,针对T2为int的情况
template<typename T>
class Test<T, int> {
public:
T value1;
int value2;
Test(T v1, int v2) {
value1 = v1;
value2 = v2;
}
};
int main() {
// 使用原类模板
Test<int, double> t1(1, 2.5);
// 使用偏特化版本
Test<double, int> t2(2.3, 5);
return 0;
}
这样通过一个具体的类定义,就可以更清晰地展示偏特化的用法:
- 原模板接受两个类型T1和T2
- 偏特化版本 fixing T2为int类型
- 根据实参类型不同,分别实例化原类模板和偏特化版本
五、递归模板
模板可以递归调用自己,实现编译期计算:
cppCopy codetemplate<int N>
struct Fib {
static const int val = Fib<N-1>::val + Fib<N-2>::val;
};
template<>
struct Fib<0> {
static const int val = 0;
};
int x = Fib<5>::val; // 编译期计算斐波那契数列
每次实例化时(如Fib<5>),递归调用会展开模板自身,直到终止条件。计算最终在编译期完成。
标签:int,C++,Fib,template,类型,编程技术,模板,特化 From: https://www.cnblogs.com/linxmouse/p/17569366.html