C++模板总结—实例化和特化

一、什么是模板?

       照猫画虎,照葫芦画瓢,所谓模板,就是代码的基本结构和内容,但该代码与类型无关,提高代码的复用。模板是泛型编程的基础。模板分为函数模板和类模板。

二、函数模板

1.函数模板的概念:该函数模板与类型无关,根据实参类型产生特定的函数版本

2.格式:

template<typename T1,typename T2,...>

返回值类型 函数名(参数列表){}

template<typename T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}

3.函数模板并不是具体的函数,传参时编译器会检查实参的类型,然后产生该类型对应的函数,这一过程称为实例化。

   隐式实例化:传入参数,编译器自己检测参数类型。如下,Add(a,b)时,实参a,b为int类型,编译器就产生一份对应的int类型的代码,但Add(a,c)时,a的类型时int, c的类型是double,由于模板参数列表中只有一个T,编译器不确定将T转化为int还是double,此时就要自己强制转化或者显示实例化。

  显式实例化:在函数名的<>中加上特定类型,如Add<int>(c,d)。若显式实例化类型不匹配,编译器会隐式实例化,失败时报错。

template<typename T>
T Add(const T& left,const  T& right)
{

	return left + right;
}
void Test()
{
	int a = 1, b = 3;
	double c = 1.1, d = 3.3;
	Add(a, b);//隐式实例化
	Add(c, d);
	//Add(a, c);不能通过编译,模板中 编译器不会进行类型转换操作
	Add(a, (int)c);//
	Add<int>(c, d);//4 显式实例化
}

4.优先选择?

如果一个非模板函数和同名函数模板同时存在,若参数类型和非模板函数完全相同,优先调用非模板函数;否则调用模板函数实例化。

int Add(int left, int right)
{
	return left + right;
}

template<typename T>
T Add( T& left,   T& right)
{

	return left + right;
}

void Test()
{
	Add(1, 3);//与非模板函数匹配
	Add<int>(1, 3);//调用模板函数
	Add<int>(1.0, 3.0);//调用模板函数
}

三、类模板

1.template<typename T1,typename T2,...>

class 类模板名

{ ... };

template<typename T>
class Vector
{
public:
	Vector(size_t capacity = 10)
		:_p(new T(capacity))
		,_size(0)
		,_capacity(capacity)
	{}

	~Vector();

	void PushBack(const T& data)
	{
		_p[_size++] = data;
	}

	void PopBack()
	{
		--_size;
	}

	size_t Size()
	{
		return _size;
	}

	T& operator[](size_t pos)
	{
		assert(pos < _size);
			return _p[pos];
	}
private:
	T* _p;
	size_t _size;
	size_t _capacity;
};

template<typename T>//类模板中的函数在类外定义时要加模板
Vector<T>::~Vector()
{
	if (_p)
		free(_p);
}

2.类模板的实例化:类名后加<type>,如下Vector<int> ,v1才是一个具体的类。

void Test()
{
	Vector<int> v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	for (size_t  i=0;i<v1.Size();i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	Vector<double> v2;
	v2.PushBack(1.1);
	v2.PushBack(2.2);
	v2.PushBack(3.3);
	for (size_t i = 0; i < v2.Size(); i++)
	{
		cout << v2[i] << " ";
	}
	cout << endl;

}

四、模板参数

1.分类:模板参数分为类型形参和非类型形参。

2.类型模板参数:模板参数列表中,跟在class或typename后的参数。

3.非类型模板参数:参数列表中,可当作常量使用。不能为浮点数,类对象和字符串。

template<typename T,size_t N=10> //<类型模板参数,非类型模板参数>
class Array
{
public:
	T& operator[](size_t index)
	{
		return _array[index];
	}

	const T& operator[](size_t index)const
	{
		return _array[index];
	}

	size_t Size()
	{
		return _size;
	}

	bool Empty()
	{
		return _size == 0;
	}

private:
	T _array[N];
	size_t _size;
};

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值