我们知道,当函数之间的函数体的整体逻辑相同c++模板类,而只是函数参数类型不同,特别是参数个数不同时,我们可以使用函数重载。对于类型不同的情形,更好的方式是函数模板,将类型参数化(可以简单理解为,函数模板的参数只是一个占位符,调用时可用具体的类型替换)。当然类也是如此,也就是类模板。

但存在的问题是c++模板类,一个统一的函数或模板并不一定能在所有类型实例下正常工作,这时就需要定义对于特定类型的特定模板实现版本。

模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。

1 函数模板特化

以下是一个函数模板特化的实例:

#include 
#include 
using namespace std;
template // 普通函数模板
T Max(T t1,T t2){
 return (t1>t2)?t1:t2;
}
 
typedef const char* CCP;
template // 函数模板特化
CCP Max(CCP s1,CCP s2){
 return (strcmp(s1,s2)>0)?s1:s2;
}
int main(){
 int i=Max(10,5); // 调用普通函数模板
 const char* p=Max("very","good"); // 调用特化函数模板
 cout<<"i:"<<i<<endl; // i:10
 cout<<"p:"<<p<<endl; // p:very
}

函数模板特化也可以使用函数重载来实现:

除了定义函数模板特化版本外,还可以直接给出模板函数在特定类型下的重载形式(普通函数)。使用函数重载可以实现函数模板特化的功能,也可以避免函数模板的特定实例的失效。例如,把上面的模板特化可以改成如下重载函数。

typedef const char* CCP;
CCP Max(CCP s1,CCP s2){
 return (strcmp(s1,s2)>0)?s1:s2;
}

2 类模板的特化和偏特化

定义模板对于特定类型的特定实现版本时,如果特定类型是具体类型(如char*),称为模板特化或整体特化,如果是一类的具体类型(如T*),称为模板部分特化,或偏特化。

c++模板类_c 模板函数类外定义_ccf推荐会议a类b类c类

模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。#include 
#include 
 
template 
class Storage
{
private:
	T m_value;
public:
	Storage(T value)
	{
		m_value = value;
	}
 
	~Storage()
	{
	}
 
	void print()
	{
		std::cout << m_value << 'n';
	}
};
 
template  // Partial-specialization偏特化(m_value为T*)
class Storage
{
private:
	T* m_value;
public:
	Storage(T* value)
	{
		m_value = new T(*value);
	}
 
	~Storage()
	{
		delete m_value;
	}
 
	void print()
	{
		std::cout << *m_value << 'n';
	}
};
 
template  //Full specialization特化(m_value为char*)
Storage::Storage(char* value)
{
	// 计算value长度length
	int length = 0; 
	while (value[length] != '')
		++length;
	++length; // +1 to account for null terminator
 
	m_value = new char[length]; //为value动态分配内存
 
	for (int count = 0; count < length; ++count) //值复制入动态内存块
		m_value[count] = value[count];
}
 
template		//Full specialization特化的析构(m_value为char*)
Storage::~Storage()
{
	delete[] m_value;
}
// Full specialization特化的函数print()(m_value为char*)
// 如果没有特化,输出一个Storage会调用Storage::print(), 只输出首字符
template
void Storage::print()
{
	std::cout << m_value;
}
 
int main()
{
	Storage myint(5); // 非特化函数模板调用
	myint.print(); //5
 
	int x = 7;
	Storage myintptr(&x); // 偏特化函数模板调用
 
	x = 9;
	myintptr.print(); // 如果没有偏特化模板定义,会输出9而不是7
 
 char *name = new char[40];
 strcpy(name, "Alex");
 	Storage myname(name);//特化函数模板调用
 	delete[] name;
 	myname.print(); //输出Alex
}

可以使用在线编译器编译运行:

-End-

限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688