C++模板(函数模板,类模板)

模板概念

函数模板可以用来创建一个通用功能的函数, 以支持多种不同形参,简化重载函数的设计。

函数模板定义如下:

template<模板参数表>
返回类型函数名(形式参数表)
{
		.....;//函数体
}

<模板参数表> (template parameter list)尖括号中不能为空,参数可以有多个,用逗号分开。模板参数主要是模板类型参数。

模板类型参数(template type parameter)代表-种类型,由关键字class 或typename (建议用typename)后加一个标识符构成,在这里两个关键字的

意义相同,它们表示后面的参数名代表一个潜在的内置或用户设计的类型。多用T表示
例子:

template<class T>
Tmy_max(Ta,Tb)
{
	return a > b? a:b;
}
int main()
{
	my_max(1223);
	my_max('a''b');
	my_max(12.2334.45);
	return 0;
}

template<class T, int N>
void PrintAr(T(&ar)[N])
{
	cout << typeid(T).name() << endl;

	for (int i = 0; i < N; ++i)
	{
		cout << ar[i] << "" << endl;
	}
}
int main()
{
	int ar[] ={ 1,2,3,4,5,6,7 };
	double dr[] = { 1.2,2.3,3.4, 4.5,5.6,6.7 };
	char str[] = { "yhping"};
	PrintAr(ar);
	PrintAr(dr);
	PrintAr(str);

}

模板有完全泛化,部分特化,完全特化之分

template<class T>
void fun(Ta)//完全泛化   //任何类型
{
     T x,y;
	cout << "T type:" << typeid(T). name() << endl ;
	cout <<" a type: "<< typeid(a). name() << endl;
}
template<class T>
void fun(T* a) //部分特化版本   //只要指针类型
{
    T x,y;
	cout << "T type:" << typeid(T). name() << endl;
	cout <<" a type: "<< typeid(a). name() << endl;
    
template<>
void fun<char*> (char* a) //完全特化  只要char*类型
{
     T x,y;
	cout << "T type:" << typeid(T). name() << endl;
	cout <<" a type: "<< typeid(a). name() << endl;
}

函数模板

类型推导出T a 的类型

泛性

template<class T>
void fun(T a)
{
	T x, y;
	cout << typeid(T).name << endl;
	cout << typeid(a).name << endl;

}
int main()
{
	int x = 10;
	const int y = 20;
	int* xp = &x;
	const int* yp = &y;
	fun(x);  //T int  a int
	fun(y);  //T const int  a const int
	fun(&x); //T int *  a int *
 	fun(&y); //T const int *  a const int *
	fun(xp); //T int *  a int *
	fun(yp); //T const int * a const int *
     return 0;
}

指针

template<class T>
void fun(T* a)
{
	T x=0, y=0;
	cout << typeid(T).name << endl;
	cout << typeid(a).name << endl;

}
int main()
{
	int x = 10;
	const int y = 20;
	int* xp = &x;
	const int* yp = &y;
	fun(&x); //T int   a int *
 	fun(&y); //T const int   a const int *
    return 0;

}

引用

template<class T>
void fun(T &a)
{
	T x=0, y=0;
	cout << typeid(T).name << endl;
	cout << typeid(a).name << endl;

}
int main()
{
	int x = 10;
	const int y = 20;
	int* xp = &x;
	const int* yp = &y;
	fun(x); //T int   a int &
 	fun(y); //T const int   a const int &
    
    fun(xp); //T int *  a int *&a              引用的指针
    fun(yp); //T const int *  a const int *&a
    
    
    return 0;

}

template<class T>    
void fun(T const &a)     //系统无法推演出int *后面的const,只能推导前面的const 所以需要在int *后加const
{
	T x=0, y=0;
	cout << typeid(T).name << endl;
	cout << typeid(a).name << endl;

}
int main()
{
	int x = 10;
	const int y = 20;

	fun(x); //T int*   a int *             等价于  int *const &p =&x 
 	fun(y); //T int const *  a int const * 等价于  const int * const &q =&y;
    
    return 0;
}

类模板

类模板里的函数都是模板函数,如果没有调用模板函数,就不会实例化该模板函数

模板参数有两种:模板类型参数和模板非类型参数

模板非类型参数
template<class T, int N>//N相当于宏
class Stack
{
    T data[N];
public:
	void push(const T& x);//模板函数
};
int main()
{
	Stack<int100> is;
	Stack<int10> ist;
}

模板类型参数

Array arr 是一个具体的类型,因为在编译后会替换成具体的int类型,就不是模板类型,模板类型是没有给出具体类型的

template<class Ttemplate<class> class Seq >  //Seq模板类型必须前面有一个模板类型参数

class Container
{
	Seq<T> seq;
public:
	void append (const T& t) { seq. push_back(t);}
	T* begin() { return seq.begin(); }
	T* end() { return seq.end(); }

};
int main()
{
	Container<int,Array> container;  //Array是一个模板类型    Array<int>是一个具体的类型,要求参数是模板类型,所有不能实例化
    return 0;
}

总结:

函数模板根据一组实际类型或(和)值构造出独立的函数的过程通常是隐式发生的,称为模板实参推演(templateargument deduction)。

为了判断用作模板实参的实际类型,编译器需检查函数调用中提供的函数实参的类型。ia 的类型为int数组,dx的类型为double数组。都被用来

决定每个实例的模板参数。该过程称为模板实参推演。

在编译main函数中,由编译函数模板(functron template)而生成的函数,称为模板函数(template function)。这两个概念须分清楚。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小新 蜡笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值