C++模板编程

C++实现模板函数技术

模板函数实现技术和模板类形式上差不多:

templateretType function_name(T t);

template<typename T>retType function_name(T t);

其中几个关键点:

  • 函数模板的签名包括模板参数,返回值,函数名,函数参数, cv-qualifier;

  • 函数模板编译顺序大致:名称查找(可能涉及参数依赖查找)->实参推导->模板实参替换(实例化,可能涉及 SFINAE)->函数重载决议->编译

  • 函数模板可以在实例化时候进行参数推导,必须知道每个模板的实参,但不必指定每个模板的实参。编译器会从函数实参推导缺失的模板实参。这发生在尝试调用函数、取函数模板地址时,和某些其他语境中;

  • 函数模板在进行实例化后会进行函数重载解析, 此时的函数签名不包括返回值(template argument deduction/substitution);

  • 函数模板实例化过程中,参数推导不匹配所有的模板或者同时存在多个模板实例满足,或者函数重载决议有歧义等,实例化失败;

  • 为了编译函数模板调用,编译器必须在非模板重载、模板重载和模板重载的特化间决定一个无歧义最佳的模板;

模板的代价

没有任何事物是完美的,模板设计如此精良也有代价的,模板的代码和通常的代码比起来,

  • 代码可读性差,理解门槛高
    一般人初学者很难看懂,开发和调试比较麻烦,对人员要求高,是跨越C++三座大山之一;

  • 代码实现稳定性代价大
    对模板代码,实际上很难覆盖所有的测试,为了保证代码的健壮性,需要大量高质量的测试,各个平台(编译器)支持力度也不一样(比如模板递归深度,模板特性等),可移植性不能完全保证。模板多个实例很有可能会隐式地增加二进制文件的大小等,所以模板在某些情况下有一定代价,一定要在擅长的地方发挥才能;

模板 SFINAL

https://blog.csdn.net/watergear/article/details/82497260

应用场景

  1. 一个类没有模板参数,但是成员函数有模板参数是可行的。代码如下:
class Util
{
public:
	template<class T>
	bool equal(T t1, T t2)
	{
		return t1 == t2;
	}
};

int main()
{
	Util aab;
	std::cout << aab.equal<int>(a, b) << std::endl;
	std::cout << aab.equal(1, 1) << std::endl;
}
  1. 在类模板的例子中栈的最大元素数量是写死的,可以使用模板的偏特化特性来自定义元素的最大数量。如下所示
template<typename T, int maxsize = 100>
class Stack
{
	//和上面的例子一样
	.....
}
template <class T,int maxsize>	//这里和上面的不一样
Stack<T, maxsize>::Stack()
{
   m_maxSize = maxsize;      	//最大数量通过外面传入
   m_size = 0;
   m_pT = new T[m_maxSize];
}

int main()
{
	int maxsize = 1024;
	Stack<int,1024> intStack;
	for (int i = 0; i < maxsize; i++) 
    	intStack.push(i);
}
  1. 具象化就是模板中特化性质。例如上面书写的交换函数,如果传入的是char* 类型,使用 = 操作只是复制了指针数据,指针指向的内存有可能会失效,所以 = 操作可能会出现问题,我们需要进行单独的操作。如下:
template<>
void swap2(char*& a, char*& b)
{
//具象化
.....
}

具象化的定义应该在有常规模板的情况下,以 template<> 打头,通过名称来指出类型,并必须要有具体的实现。
函数在调用的过程时,编译器调用顺序是:常规函数 > 具体化模板函数 > 常规模板。
4. 实例化
显示实例化

template void swap2<int>(int& a, int& b); //声明时显示实例化,只需要声明,不需要实现

int a = 1, b= 2;
swap<int>(a, b);	//使用时显示实例化

隐式实例化 类似普通的函数调用,在使用模板时,根据使用的类型,编译器进行推导,生成相应类型的实例。方便程序员的书写,但是增加编译器的负担。如下所示

swap(a, b);	//隐式实例化,和显示实例化的结果是一样的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值