C++ 模板、模板全特化、模板偏特化

模板定义:模板就是实现代码重用机制的一种工具,他可以实现类型参数化,即把类型定义为参数,从而实现了真正的代码可重用性。
模板可以分为两类:一个是函数模板,一个是类模板

大白话:C++是一门强类型语言,编写一段通用的逻辑,可以把任意类型的变量传进去处理,通过通用逻辑设计为模板,摆脱了类型的
限制,极大地提升了代码的可重用性。

模板实例化:模板定义本身不参与编译,而是编译器根据模板的用户使用模板提供的类型参数生成代码,再进行编译。用户提供不同的
类型参数,就会实例化处不同的代码。

类模板描述了一组相关的类或数据类型,他们只能通过类型来区分:整数值、指向(或引用)具有全局链接的变量的指针、其他组合。
类模板尤其适用于描述通用但类型安全的数据结构。

类模板的使用:
template <类型形式参数>
class 类名
{
//类声明体
};
template <类型形式参数>
返回类型 类名 <类型>::成员函数名1(形参)
{
//成员函数定义体
}
. . .
template <类型形式参数>
返回类型 类名 <类型>::成员函数名N(形参)
{
//成员函数定义体
}

#include <iostream>
using namespace std;

template <class T>
class Compare
{
public:
	bool myequal(T a, T b);
};

template <class T>
bool Compare<T>::myequal(T a, T b)
{
	return a == b;
}

/*
类模板全特化
所谓模板全特化限定死模板实现的具体类型
*/

template <>
class Compare<float>
{
public:
	bool myequal(float a, float b);
};

bool Compare<float>::myequal(float a, float b)
{
	return std::abs(a - b) < 0.001;
}

int main01()
{
	Compare<int> C;
	bool res = C.myequal(1, 1);
	Compare<float> C2;
	bool res2 = C2.myequal(1.001, 1.005);
	if (res)
		cout << "==" << endl;
	else
		cout << "!= " << endl;
	if (res2)
		cout << "2: ==" << endl;
	else
		cout << "2: != " << endl;
	return 0;
}
/*
模板偏特化
偏特化是指提供另一份template定义式,而其本身仍为 templatized ,这是针对于 template 参数更进一步的条件限制所设计出来的一个特化版本
也就是说如果有多个类型,那么只限定其中的一部分
*/

template <class T1, class T2>
class Test
{
public:
	Test(T1 a, T2 b) :_a(a), _b(b)
	{
		cout << "模板化" << endl;
	}
private:
	T1 _a;
	T2 _b;
};

//模板全特化
template <>
class Test<int, int>
{
public:
	Test(int a, int b) :_a(a), _b(b)
	{
		cout << "模板全特化" << endl;
	}
private:
	int _a;
	int _b;
};

//模板偏特化
template <class T>
class Test<int, T>
{
public:
	Test(int a, T b):_c(a), _d(b)
	{
		cout << "模板偏特化" << endl;
	}
private:
	int _c;
	T   _d;
};

int main02()
{
	Test<double, double> t1(1.01, 1.01);
	Test<int, int> t2(1, 1);
	char arr[] = "111";
	Test<int, char*> t3(2, arr);
	return 0;
}

函数模板
函数模板一般定义:

template <类型形式参数> //类型形式参数即此格式:<typename 形参> 或 <class 形参>
返回类型 函数名(形参)
{
//函数定义体
}

//普通模板函数
template <class T1, class T2>
bool compare(T1 a, T2 b)
{
	cout << "普通模板" << endl;
	return a == b;
}

//函数模板特化
//函数模板特化和类模板特化本质是一样的,是对模板参数的特殊处理:
template<>
bool compare(const char* a, const char* b)
{
	cout << "函数模板特化" << endl;
	return strcmp(a, b) == 0;
}

int main()
{
	cout << compare(1, 2) << endl;

	cout << compare("ab", "ab") << endl;
}

总结:
1.函数模板只有特化,没有偏特化
2.模板、模板的特化和模板的偏特化都存在的情况下,编译器在编译阶段进行匹配,优先特殊的。
3.模板函数不能是虚函数;因为每个包含虚函数的类具有一个 virtual table, 包含该类的所有虚函数的地址,
因此 vtable 的大小是确定的。模板只有被使用时才被实例化,将其声明为虚函数会使 vtable 的大小不确定。
所以,成员函数模板不能为虚函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值