C++模板的特化(specialization)和偏特化(partial specialization)

模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。

类模板全特化:

全特化即将模板类型里的所有类型参数全部具体指明之后处理,如下

template<typename T,typename C>
struct A
{
    A(){cout<<"泛化版本构造函数"<<endl;}
    void func()
    {
        cout<<"泛化版本"<<endl;    
    }
};
 
template<>
struct A<int,int>
{
   A(){cout<<"int,int特化版本构造函数"<<endl;}
   void func()
   {
       cout<<"int,int特化版本"<<endl;    
   } 
};
 
template<>
struct A<double,double>
{
   A(){cout<<"double,double特化版本构造函数"<<endl;}
   void func()
   {
       cout<<"double,double特化版本"<<endl;    
   } 
};


int main()
{
    A<int,double> a;//调用泛化构造函数
    a.func();//调用泛化版本函数
    A<int,int> a;//调用int,int特化构造函数
    a.func();//调用int,int特化版本函数
    A<double,double> a;//调用double,double特化构造函数
    a.func();//调用double,double特化版本函数
}

template<>中为空,代表所有类型都在下面特殊化处理,上面相当于对int,int和double,double两种类型进行了分别的处理,其他类型依然是泛化版本。

对类中的某个成员函数进行特化处理

还是以上面给的例子为基础,特化func()成员函数,当A的模板参数为<int,double>时,调用特化版的func()。

template<>
void A<int,double>::func
{
    cout<<"int,double特化版本函数"<<endl;
}
 
int main()
{
    A<int,double> a;//调用泛化版本构造函数
    a.func();//调用int,double特化版本函数
}

类模板的偏特化

类模板偏特化(局部特化):顾名思义,只特殊化几个参数或者一定的参数范围

个数偏特化

template<typename T,typename C,typename D>
struct A
{
	void func()
	{
		cout << "泛化版本" << endl;
	}
};
 
template<typename C>
struct A<int,C,int>
{
	void func()
	{
		cout << "int,C,int偏特化版本" << endl;
	}
};
 
template<typename C>
struct A<double, C, double>
{
	void func()
	{
		cout << "double,C,double偏特化版本" << endl;
	}
};
int main()
{
	A<double, int, int> a;
	a.func();//调用泛化版本
	A<int, char, int> b;
	b.func();//调用int,C,int偏特化版本
	A<double, int, double> c;
	c.func();//调用double,C,double偏特化版本
}

template<>括号中存留的参数是依然可以任意填的参数。

STL中的一个个数偏特化例子
在这里插入图片描述

范围偏特化

注意范围二字,比如const int属于int的一个小范围,int *和const int*属于int的一个小范围,int&属于int的一个小范围,int&&属于int的一个小范围

template<typename T>
struct A
{
	void func()
	{
		cout << "泛化版本" << endl;
	}
};
 
template<typename T>
struct A<const T>
{
	void func()
	{
		cout << "const T版本" << endl;
	}
};
 
template<typename T>
struct A<T*>
{
	void func()
	{
		cout << "T*版本" << endl;
	}
};
 
template<typename T>
struct A<T&>
{
	void func()
	{
		cout << "T&版本" << endl;
	}
};
 
template<typename T>
struct A<T&&>
{
	void func()
	{
		cout << "T&&版本" << endl;
	}
};
int main()
{
	A<int> a;
	a.func();
	A<const int> b;
	b.func();
	A<int *> c;
	c.func();
	A<const int *> d;
	d.func();
	A<int&> e;
	e.func();
	A<int&&> f;
	f.func();
}

在这里插入图片描述

记住这种情况的template<>中还是要填上原有的大类型,且const T*属于T*不属于const T

STL中的一个范围偏特化例子
在这里插入图片描述

函数模板全特化:

template<typename T,typename C>
void func(T &a, C &b)
{
	cout << "------------------------" << endl;
	cout << "泛化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
template<>
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "int,int特化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
 
int main()
{
	double a = 1.0;
	double b = 2.0;
	func(a, b);
	int c = 3;
	int d = 4;
	func(c, d);
}

在这里插入图片描述

假如说存在非模板的重载函数,且其与特化的一个版本一样

,如下所示:
template<typename T,typename C>
void func(T &a, C &b)
{
	cout << "------------------------" << endl;
	cout << "泛化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
template<>
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "int,int特化版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
 
void func(int &a, int &b)
{
	cout << "------------------------" << endl;
	cout << "重载版本" << endl;
	cout << a << endl;
	cout << b << endl;
	cout << "------------------------" << endl;
}
int main()
{
	double a = 1.0;
	double b = 2.0;
	func(a, b);
	int c = 3;
	int d = 4;
	func(c, d);
	int e = 3;
	int f = 4;
	func<int, int>(e, f);
}

在这里插入图片描述
则在你不特地指明参数类型时,编译器会优先选择重载普通函数版本。

函数模板偏特化:

函数模板不能偏特化!!!!!!!!!!!!!

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值