模板概念,函数模板定义、调用

000模板与泛型编程概述

(1)概述

  • C++标准库中很多内容使用了模板与泛型技术。如vector等
  • 1.泛型编程就是以独立于任何特定类型的方式编写代码,在泛型编程时,我们需要提供具体程序实例
  •   所操作的类或者值。
    
  • 2.模板是泛型编程的基础,模板是创建类或者函数的蓝图或者公式。我们给这些蓝图或者公式提供足够的信息,
  •   然这些蓝图或者公式提供足够的信息,在编译时候生成真正的类。
    
  • 3.模板支持将类型作为参数的程序设计方式,从而实现了对泛型设计的直接支持,也就是说c++模板机制允许
  •   在定义类、函数时将类型作为参数。
    
  • 4.模板一般分为函数模板和类模板。

001模板函数的定义和使用

#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>

using namespace std;
//两个数字相加
int AddFunction(int a,int b)
{
	int Tem = a + b;
	return a + b;
}

int AddFunction(double a,double b)
{
	int tem = a + b;
	return tem;
}

//两个函数只有参数类型不同
template <typename T>//声明一个类型为T的模板函数
T FunctionTemplate (T a,T b)
{
	T tem = a + b;
	return tem;
}
/*
 * 1.函数模板以template开头,后边跟<>。<>里面叫模板参数列表,多个参数使用逗号,分开
 * 2.<>里面必须具有一个模板参数,模板参数前面有个typename关键字,也可以用class,表示是个类型名。
 * 3.如果模板参数列表里面有多个参数,那么就要使用多个typename,class template <typename T,typename Q>
 * 4.模板参数列表里面表示在函数定义中要用到的“类型”或者“值”,与函数参数列表类似。
 * 5.调用的时候使用指定模板实参,模板名字<模板实参>(函数参数)
 * 6.模板函数根据调用传递的实参,在编译的时候确定类型。
 */

int main(void)
{
	//编译器根据调用的实参去推断模板函数里面的参数类型。有时候需要提供,有时候推断。
	//有时候根据根据实参是推断不出模板的类型,需要使用<>提供出来。
	int Sum = FunctionTemplate<int>(32, 44);
	int Sum02 = FunctionTemplate(44.00, 34.454);//可以不提供模板类型参数,编译器推断是double类型
	//调用时候,编译器 推断出模板类型之后,就实例化一个特定版本类型的函数。
	
	
	system("pause");
	return 0;
}

/*
*(1)函数模板的定义
*
*(2)函数模板的使用
*
*(3)
*
*
*/

002非类型参数模板函数

#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>

using namespace std;

template <typename T,int S>//typename表示T是一个类型,T是一个类型参数,
T FunctionTemplate(T a)
{
	T tem = a + S;
	return tem;
}


//非类性能参数
template<unsigned a, unsigned b>
int FunctionTemplate02()
{
	return a + b;
}

//非类型参数--比较字符书否相同
template<int L1, int L2>
int CharCompare(const char(&p1)[L1], const char(&p2)[L2])
{
	return strcmp(p1, p2);
}

int main(void)
{

	int Sum01 = FunctionTemplate02<23, 23>();//显式指定模板参数,在<>指定额外的信息。
	int a = 12;
	//int Sum02 = FunctionTemplate02<a, 32>();//error,必须用常量,编译时候就要确定

	int Sum03 = FunctionTemplate<int, 12/*指定int S=12,T的类型是int*/>(13);//25--显式指定模板参数,int类型为12
	int Sum04 = FunctionTemplate<double, 13>(28);//系统以<>内传递的参数为准 28.00000000
	cout << Sum04 << endl;

	//模板函数CharCompare
	int result01 = CharCompare("jisuanji", "jisuanjizu");//没有提供费类型模板参数,自己推断出来L1,L2
	//系统实例化为int CharCompare(const char(&p1)[9], const char(&p2)[11])
	int result02 = CharCompare<9, 11>("jisuanji", "jisuanjizu");//显式指定非类型模板参数
	
	
	system("pause");
	return 0;
}

/*
*(1)模板参数列表
*	1.在模板参数列表里面还可以定义非类型参数。
*	2.非类型参数表示的是一个数值,不能使用typename修饰。
*	3.我们需要使用以前学习的传统类型名来指定非类型参数,比如非类型参数S是个整形,可以使用int S
*	T FunctionTemplate(T a,int S)
*
*(2)为什么需要非类型参数?
*	当模板被实例化的时候,这种非类型模板参数的值,或者是用户提供的,或者是编译器推断的,都有可能。
*		但是这些值都得是常量表达式,因为实例化这些模板都是在编译的时候确定的。
*
*(3)模板定义并不会生成代码,只有在我们调用函数模板时候,编译器为我们实例化一个特定的版本函数后才会生成代码。
*	编译器生成代码的时候,需要找到函数的函数体。所以函数模板的定义通常都是在.h中。
*
*
*/

版权声明:本文为qq_39885372原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。