C++中的模版

一、函数模版

函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。

函数模板类型自推:能够根据参数类型自动推演出模板类型参数。

1、语法格式

template<类型形式参数表>

返回类型 函数名(形式参数表)

{ }

2、函数模板的实例化

编译时期根据模板调用的类型方式,自动生成一份对应于该类型的代码 
1)显示实例化:显示实例化也称为外部实例化。在不发生函数调用的时候将函数模板实例化,或者在不使用类模板的时候将类模板实例化称之为模板显示实例化。

2)隐式实例化:函数模板隐式实例化指的是在发生函数调用的时候,如果没有发现相匹配的函数存在,编译器就会寻找同名函数模板,如果可以成功进行参数类型推演,就对函数模板进行实例化。


隐式实例化:​​​​​​

//函数模板
template<typename T>
bool compare(const T a,const T b)
{
	cout << "bool compare(T a, T b)   " << typeid(T).name() << endl;
	return a > b;
}

int main()
{
    //隐式实例化
    compare(3,4);
    return 0;
}

显式实例化: 

template<typename T>
bool compare(const T a,const T b)
{
	cout << "bool compare(T a, T b)   " << typeid(T).name() << endl;
	return a > b;
}


//显示实例化
template void compare<int>(const int&,const int&);

 3、函数模版的特例化
特例化是实例化一个模板,而非重载它。特例化不影响参数匹配。参数匹配都以最佳匹配为原则。

格式:

template<>

返回类型 函数名<形式参数表>(参数表)

{ }

//函数模板
template<typename T>
bool compare(const T a,const T b)
{
	cout << "bool compare(T a, T b)   " << typeid(T).name() << endl;
	return a > b;
}



//函数模板的特例化
typedef char*  CharPtr;
template<>
bool compare<CharPtr>(const CharPtr a, const  CharPtr b)
{
	cout << "bool compare<const char *>(const char * a,const  char* b)" << endl;

	return strcmp(a, b) > 0;
}

4、函数模版的重载与非模版函数

1) 函数模板可以像普通函数一样被重载
2) C++编译器优先考虑普通函数
3) 如果函数模板可以产生一个更好的匹配,那么选择模板
4) 可以通过空模板实参列表的语法限定编译器只通过模板匹配

//函数模板
template<typename T>
bool compare(const T a,const T b)
{
	cout << "bool compare(T a, T b)   " << typeid(T).name() << endl;
	return a > b;
}

//函数模板的特例化
template<>
bool compare<CharPtr>(const CharPtr a, const  CharPtr b)
{
	cout << "bool compare<const char *>(const char * a,const  char* b)" << endl;

	return strcmp(a, b) > 0;
}

//非模板函数
bool compare(const double a, const double b)
{
	cout << "bool compare(const double a, const double b)" << endl;
	return a > b;
}

//函数模板的重载
template<typename T>
bool compare(T *arr1,int len1,T *arr2,int len2)
{
	cout << "bool compare(T *arr1,int len1,T *arr2,int len2)  " << typeid(arr1).name()<<endl;
	int i, j;
	for ( i = 0, j = 0; i < len1&&j < len2; i++, j++)
	{
		if (arr1[i] > arr2[j])
		{
			return true;
		}
	}
	if (i == len1)
	{
		return false;
	}
	return true;
}

 5、多个形式参数列表的使用

#include<iostream>
using namespace std;

template<typename T>
bool Mygre(T a, T b)
{
	return a > b;
}
typedef char * CHARPtr;
template<>
bool Mygre<char *>(const CHARPtr a, const CHARPtr b)
{
	return strcmp(a,b) > 0;
}


template<typename T>
bool Myless(T a, T b)
{
	return a < b;
}
typedef char * CHARPtr;
template<>
bool Myless<char *>(const CHARPtr a, const CHARPtr b)
{
	return strcmp(a, b) < 0;
}

template<typename T,typename PRE>
void sort(T str[],int len,PRE pre)
{
	for (int i = 0; i < len; i++)
	{
		for (int j = i+1; j < len; j++)
		{
			if (pre(str[i],str[j]))
			{
				T tmp = str[i];
				str[i] = str[j];
				str[j] = tmp;
			}
		}
	}
	for (int i = 0; i < len; i++)
	{
		cout << str[i] << "   ";
	}
	cout << endl;
}

int main()
{
	int str[10] = { 50, 10, 25, 16, 58, 2, 0, 15, 25, 12 };
	sort(str, 10, Mygre<int>);
	sort(str, 10, Myless<int>);
	char *arr[] = {"abc","bca","cba"};
	sort(arr, 3, Mygre<char*>);
	sort(arr, 3, Myless<char*>);
	return 0; 
}

二、类模版

是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。

模板的类型参数由关键字class 或关键字typename 及其后的标识符构成。在模板参数表中关键字class 和typename 的意义相同。

1、格式:

template <类型名 参数名1,类型名 参数名2,…>

class 类名

{

类声明体

};

2、类模板的实例化

1)隐式实例化

template<typename T>
class Person
{
public:
	A(T name)
    {
		_name = name;
	}
	void show()
	{
		cout<<"_name:"<< _name <<endl;
	}
private:
	T _name;
};

int main()
{
    //显示模板实参的隐式实例化
	Person<char> a('a'); 
	a.show();
}

2)显示实例化

template<typename T>
class Person
{
public:
	A(T name)
    {
		_name = name;
	}
	void show()
	{
		cout<<"_name:"<< _name <<endl;
	}
private:
	T _name;
};

template class Person<int>;

3、类模板中成员方法的模板和类模板中成员方法的模板的特例化

template<typename T>
class Carry
{
public:
	Carry(int resize = 2)
	{
		cout << "Carry(int resize = 0)" << endl;
		_arr = new T[resize];
		_len = resize;
		_sizeVal = 0;
	}
	~Carry()
	{
		cout << "~Carry()" << endl;
		delete[]_arr;
	}

    //类模版中成员方法的模板
	template<typename U>
	int find(U val);
	{
		cout << "template<typename U> int find(U val)" << endl;
		for (int i = 0; i < _sizeVal; i++)
		{
			if (_arr[i] == val)
			{
				return i;
			}
		}
		return -1;
	}

    //类模版中成员方法的模板的特例化
	template<>
	int find<char*>(char * val);
	{
		cout << "template<> int find<char*>(char * val)" << endl;
		for (int i = 0; i < _sizeVal; i++)
		{
			if (strcmp(_arr[i],val) == 0)
			{
				return i;
			}
		}
		return -1;
	}


private:
	T *_arr;
	int _len;
	int _sizeVal;
};

猜你喜欢

转载自blog.csdn.net/wry_sunny_/article/details/86540902