c++模板编程-模板类的特例化和部分特化

文章介绍了C++中的类模板特化,包括全特化和部分特化。全特化允许为特定类型定义不同的行为,如示例中为类A特化Test模板。部分特化则针对模板的部分参数进行特殊处理,如模板针对指针的处理。同时,文章提到了多参数模板特化及可能出现的歧义问题,并给出了解决方案。

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

类模板可以对某一个模板参数进行特化,这使得我们可以对某一个类型进行优化(你最好真是在优化),或者是针对某一个进行类型实例化后的特殊处理。

全特化

如我们有以下一个简单的类模板,它提供两个公开函数,calculate计算两个T类型并返回,print使用cout打印T类型变量,如下:

template<typename T>
class Test
{
public:
	T calculate(T a, T b) 
	{ 
		return a + b;  
 	}

	void print(T t)
	{
		cout << t << endl;
	}
};

此后,我们又有了一个类A,它不提供加法运算符的重载以及cout的重载,我们将特化使用 class A实例化 Test模板的行为:

class A
{
public:
	int id = 10;
};

//全特化,也可以只实现部分功能,比如只实现calculate,不实现print
template<>
class Test<A>
{
public:
	void calculate()
	{
		cout << "Unsupported type!" << endl;
	}

	void print(A a)
	{
		cout << a.id << endl;
	}
};

可以看出,对于被特化的模板,出现 T 的地方,都应该替换为用于特化类模板的类型,接下来我们使用被特化的模板

//使用 int 实例化
Test<int> tInt;
cout << tInt.calculate(1, 2) << endl;
tInt.print(3);

//实例化为类型 A 特化的模板
Test<A> tA;
tA.calculate();
tA.print(A());

以上实例化为类型 A 特化的模板的使用,调用calculate函数会打印 “Unsupported type!”,调用print函数则会打印 A 类型的id;这种行为我们称之为全特化

部分特化

有了全特化,对应的自然有部分特化(Partial Specialization),很多人将其翻译为 偏特化,我认为这是难以理解且不够形象的。

如我们部分特化一个 Test 模板来对指针进行特殊处理:

template<typename T>
class Test<T *>
{
public:
	T calculate(T *a, T *b)
	{
		return *a + *b;
	}
};

int main()
{
	Test<int*> t;
	int a = 1, b = 2;
	cout << t.calculate(&a, &b) << endl;
}

多模板参数的部分特化

多参数的类模板,也可以进行部分特化,如:

template <typename T1, typename T2>
class Test
{
public:
	void print(T1 t1, T2 t2)
	{
		cout << t1 << t2 << endl;
	}
};

template <typename T>
class Test<T, int>
{
	//...
};

template <typename T>
class Test<int, T>
{
public:
	//...
};

template <>
class Test<int, float>
{
public:
	//...
};

相当自由、灵活,但是需要注意多参数模板部分特化时的歧义问题,比如以下场景:

template <typename T1, typename T2>
class Test
{
public:
	void print(T1 t1, T2 t2)
	{
		cout << t1 << t2 << endl;
	}
};

template <typename T>
class Test<T, T>
{
	//...
};

template <typename T1, typename T2>
class Test<T1 *, T2 *>
{
public:
	//...
};


int main()
{
	Test<int *, int *> t; //错误,class Test<T, T> 和 class Test<T1 *, T2 *> 都匹配
}

此时就需要一个单独的特化,来处理两种类型一样的指针:

template <typename T>
class Test<T *, T *>
{
public:
	//...
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为啥不吃肉捏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值