C++知识点62——模板实参推断与函数模板的特化

一、函数指针与模板实参推断

可以用函数模板初始化一个函数指针或给一个函数指针赋值

示例

template <typename T>
int comp(const T &a, const T &b)
{
	return 0;
}

int main(int argc, char const *argv[])
{
	int (*pf)(const int &, const int &)=comp;
}

上述代码通过函数指针的形参类型指定了函数模板的模板参数T的类型为int

 

示例2

void func(int (*pf)(const int &, const int &)){}
void func(int (*pf)(const string &, const string &)){}

int main(int argc, char const *argv[])
{
	func(comp<int>);
}

func是个重载函数,如果把函数模板传入func后,会引起二义性错误,因为此时,编译器无法确定模板参数到底是int还是string,所以需要显示指定模板参数

 

二、模板参数与引用

如果函数模板的模板参数作为引用类型的形参,那么,当传入一个数组时,形参的类型是数组的引用

示例

template <typename T>
const T & max(const T &a, const T &b)
{
	cout<<typeid(a).name()<<endl;
	cout<<typeid(b).name()<<endl;
	return a>b?a:b;
}

int main(int argc, char const *argv[])
{
	int a[]={1,2,3,4};
	int b[]={2,3,4,5};
	::max(a, b);
	::max("1234", "2345");
	return 0;
}

这里T被分别推断为int数组和char数组,因为T同时作用于两个形参,且实例化后,形参的类型是数组的引用,所以数组的大小必须相同

 

如果函数模板的模板参数作为值类型的形参,那么,当传入一个数组时,形参的类型会退化成指针

template <typename T>
const T & max(T a, T b)
{
	cout<<typeid(a).name()<<endl;
	cout<<typeid(b).name()<<endl;
	return a>b?a:b;
}

int main(int argc, char const *argv[])
{
	int a[]={1,2,3,4};
	int b[]={2,3,4,5};
	::max(a, b);
	::max("1234", "2345");
	return 0;
}

此时,T的类型只是个指针,所以,并不要求数组的大小

上述两点其实并没有什么特别,和以前一样,当我们把一个数组传递给一个类型是数组的引用的形参时,数组不会退化成指针,当我们把一个数组传递给一个类型是数组的形参时,数组形参会变成一个指针

 

三、const与模板实参推断

如果函数模板的模板参数作为普通形参,那么当传入const类型的实参

template <typename T>
void constest(T a){cout<<typeid(a).name()<<endl;}

int main(int argc, char const *argv[])
{
	const int a=10;
	constest(a);
}

和之前一样,对于值传递,顶层const会被忽略

虽然传入了const int,但是此时T被指定为int

 

四、函数模板的特化

类模板可以被特化,函数模板也可以被特化,规则也是在template后面加个<>

示例

template <typename T>
int comp(const T &a, const T &b)
{
	cout<<typeid(T).name()<<endl;
	return 0;
}

template <>
int comp(const string &a, const string &b) 
{
	return 0;
}

和类模板一样,函数模板特化本质依旧是实例化的一种,并不是重载

和类模板不同的是,函数模板不能局部特化

 

参考

《C++ Template》

《C++ Primer》

 

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值