C++:模板:非类型模板参数、模板的特化、类型萃取(如何实现一个通用的拷贝函数?)

本文介绍了C++模板参数的概念,包括类型形参和非类型形参,并详细解释了模板特化的应用,例如函数模板特化和类模板特化。通过具体实例展示了如何实现模板的全特化和部分特化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 模板参数:包括类型形参和非类型形参两种。
    类型形参:出现在模板的参数列表中,跟在class或者typename之后的参数类型名称。
    非类型参数:用一个常量作为类作为类(函数)模板的一个参数,在类(函数)模板中可以把该参数当成常量来使用。

注意:非类型参数不允许为浮点数、类对象以及字符串。
非类型的模板参数必须在编译时就能确认结果。

template <class T ,size_t N = 10>
这里的size_t N = 10 就是非类型参数
  • 模板的特化:在原来模板的基础上,针对特殊类型进行特殊化的实现方式 ;包括函数模板特化和类模板特化两种。
  • 函数模板特化:
    比如:在下面代码中,我们就不能比较两个字符串是否相等。
template <class T>
bool IsEqual(T& m, T& n){
	return m == n;
}

因此,针对string类型的对象,我们就要是该模板特化来保证对string类型也适用。
下面是针对string类进行的模板特化
注意特化的格式!!!

template <>
bool ISEqual<char*> (char*& m, char*& n){
	if (strcmp(m, n) == 0)
		return true;
	else
		return false;
}

所以,总结模板特化的步骤为:
1、要有基础模板;
2、template后面跟一对空的尖括号<>;
3、函数名后跟一对<>,里面放需要特化的类型;
4、函数的形参表必须要和模板函数的基础参数类型完全相同。

  • 类模板特化:如下图
    在这里插入图片描述
    现在一一举例:
template <class T1,class T2>
class Data{
public:
	Data(){
		cout << "Data<T1,T2>" << endl;
	}
private:
	T1 _d1;
	T2 _d2;
};
无论T1,T2给什么类型,输出的结果都是Data<T1,T2>

全特化:
template<>
class Data<int ,char>{
public:
	Data(){
		cout << "Data<int,char>" << endl;
	}
private:
	int _d1;
	char _d2;
};
此时,当T1、T2分别给int,char型时,输出的结果为Data<int,char>

部分特化:形式如全特化,只特化部分参数

参数更进一步的限制:(可以是指针或引用)
template <typename T1,typename T2>//typename后面规定参数为类型参数。
class Data<T1*, T2*>{
public:
	Data(){
		cout << "Data<T1*,T2*>" << endl;
	}
private:
	T1 _d1;
	T2 _d2;
};
此时,当T1、T2分别给int*,int*时,输出的结果为Data<int*,int*>
  • 如何实现一个通用的拷贝函数?
    一般情况下,我们会选择用memcpy函数来实现拷贝,但是这种方法在对string类进行拷贝的时候会出问题,因为memcpy属于浅拷贝,对string使用时会产生野指针,所以string一般用for循环+赋值的方法来实现拷贝,但是如果所有的类型都用这种方法来拷贝,代码的效率就会比较低。所以,我们可以想办法把这两者结合起来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值