栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

模板概念

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

函数模板定义如下:

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

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

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

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

template
Tmy_max(Ta,Tb)
{
	return a > b? a:b;
}
int main()
{
	my_max(12,23);
	my_max('a','b');
	my_max(12.23,34.45);
	return 0;
}

template
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
void fun(Ta)//完全泛化   //任何类型
{
     T x,y;
	cout << "T type:" << typeid(T). name() << endl ;
	cout <<" a type: "<< typeid(a). name() << endl;
}
template
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* a) //完全特化  只要char*类型
{
     T x,y;
	cout << "T type:" << typeid(T). name() << endl;
	cout <<" a type: "<< typeid(a). name() << endl;
}

函数模板

类型推导出T a 的类型

泛性

template
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
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
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    
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//N相当于宏
class Stack
{
    T data[N];
public:
	void push(const T& x);//模板函数
};
int main()
{
	Stack is;
	Stack ist;
}

模板类型参数

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

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

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

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

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

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

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892819.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号