C++ 进阶之路:非类型模板参数、模板特化与分离编译详解

目录

非类型模版参数

类型模板参数

非类型模板参数

非类型模板参数的使用

模板的特化

函数模板的特化

类模板的特化

全特化与偏特化

偏特化的其它情况

模板的分离编译

什么是分离编译

为什么要分离编译

为什么模板不能分离编译

普通的类和函数都是可以分离编译的。

同样是分离编译,普通函数/类可以,函数模板、类模板为什么不行??? 

编译链接有哪些过程?

链接的时候到底做了什么??

解决模板不能分离编译的方法

显示实例化

不要分离编译


非类型模版参数

在 C++ 中,非类型模板参数是一种在模板定义中使用的参数类型,它不是一个数据类型,而是一个具体的值或对象引用。

类型模板参数

//类型模板参数
template<class T>
class A
{};

非类型模板参数

 那么什么是非类型模板参数呢?首先,我们来观察以下代码

假设我想要一个数组的大小一个是100,一个是1000,只能把这个 N 要么给 100 要么给1000,或者再定义一个类出来一个N 100一个 N 1000,如果这样改的话代码过,代码处理不同类型不够灵活,所以我们就有了非类型模板参数

#define N 100
template<class T>
class Array
{
private:
	T _a[N];
};
int main()
{
	Array<int> a1;  // 100
	Array<int> a2;  // 1000
	return 0;
}

非类型模板参数的使用

 非类型模板参数的使用和类型模板参数的使用类似,也是一样的传参。

#include <iostream>
using namespace std;
//#define N 100
//#define N 1000

//类型模板参数,非类型模板参数
template<class T, int N>
class Array
{
private:
	T _a[N];
};
int main()
{
	Array<int, 100> a1;  // 100
	Array<int, 1000> a2;  // 1000
	cout << sizeof(a1) << endl;
	cout << sizeof(a2) << endl;
	return 0;
}

  这里的N是常量,不能修改的,因为数组的大小是常量。

template<class T, int N>
class Array 
{
public:
	Array() 
	{
		N = 10; //不能修改
	}
private:
	T _a[N];
};

int main()
{
	Array<int, 100> a1;  // 100
	Array<int, 1000> a2;  // 1000
	cout << sizeof(a1) << endl;
	cout << sizeof(a2) << endl;
	return 0;
}

 注意点:

记住一点:模板参数不一定全部传类型,也有可能传整型来固定大小啊。非类型模板参数是一个参数,不是什么类型都能做非类型模板参数的。

double 和 自定义类型等不能作为非类型模板参数。

#include <iostream>
using namespace std;

template<class T, char ch> 
//char short可以做非类型模板参数,还有long long / long / int / short / char 整型家族

//以下类型不能作为非类型模板参数
template<class T, double D> 
template<class T, string s>
class B
{};

模板的特化

模板的特化:针对某些类型的特殊化处理

函数模板的特化

针对某一种模板的具体类型,要根原来的模板做不一样的处理,就写一个特化,以下是函数模板的写法,针对const char* 类型进行特殊处理。

#include <iostream>
#include <string>
using namespace std;
//原模板
template<class T>
bool IsEqual(T& left, T& right)
{
	return left == right;
}
//模板的特化:针对某些类型的特殊化处理
template<>
bool IsEqual<const char*>(const char*& left, const char*& right)
{
	return strcmp(left, right) == 0;
}
int main()
{
	int a = 0, b = 1;
	cout << IsEqual(a, b) << endl;
	//这里是指针在比较,而是想比较ASCII码的值,这种情况下就需要使用到特化
	const char* p1 = "hello";
	const char* p2 = "world";
	cout << IsEqual(p1, p2) << endl;
	return 0;
}

类模板的特化

#include <iostream>
using namespace std;
//原类模板
template<class T1, class T2>
class Date
{
public:
	Date()
	{
		cout << "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值