C++中的模板

时间:2020-02-23 14:30:07  来源:igfitidea点击:

C++中的模板是通用编程的抽象版本,其中代码以独立的方式编写,即完全独立于同一程序中的其他代码块。

使用模板,您可以创建通用方法和类,其中数据类型与数据一起作为参数传递,以减少代码冗余。

我们可以创建一个可以处理不同数据类型的单一方法和/或者类,而不必重新定义函数的结构或者定义新的函数。

因此,模板使程序员可以定义方法或者类,而无需事先了解将要处理的变量的数据类型。

在C++中使用模板

C++中的模板类似于系统编程中宏的工作逻辑。

  • 在生成要编译的代码时,该代码仅包含方法/类。

  • 在编译代码时,编译器会根据函数调用将函数/类替换为所需或者所需的数据类型。

因此,在模板中,单个函数/类可处理其中具有多种数据类型的数据。

模板入门

C++中的模板可用于创建和定义以下内容:

  • Classes:创建一个包含任何模板类型或者非模板类型变量作为参数的模板类。

  • Function/Methods:创建一个包含任何模板类型或者非模板类型变量作为参数的Template函数。

1. C++中的功能模板

功能模板在程序的单个流程中工作并处理功能内的不同数据类型。

语法:

template <class type> type fun_name(argument_list)  
{  
  //body  
}  

  • " type"只是一个占位符/模板参数,它表示函数/类的数据类型。

  • " class"基本上是用来描述模板声明中泛型函数/类类型的关键字。
    关键字class也可以由typename代替。

例:

#include <iostream>  
using namespace std;  
template<class T> T subtract(T x,T y)  
{  
  T res = x-y;  
  return(res);  
    
}  
int main()  
{  

cout<<"Subtraction of numbers of integer type:\n"<<subtract<int>(3,2);  

cout<<"\nSubtraction of numbers of float type:\n"<<subtract<float>(5.3,3.2); 
 
 
return 0;  
}  

在上面的代码片段中,我们创建了一个名为减法的模板函数,带有两个变量– x,y作为其参数。

在程序编译期间,它将特定的数据类型分配给函数。
即在以动态类型运行代码时,它会检查传递给调用函数的参数的类型,然后提前执行。

输出:

Subtraction of numbers of integer type:
1
Subtraction of numbers of float type:
2.1

功能模板的多个参数

C++中的函数模板中可以包含多种通用类型的参数。

语法:

template<class T1, class T2,.....>  
type fun_name (parameters of generic type T1, T2....)  
{  
  //body of function.  
}  

其中类" T1"和" T2"描述了通用函数的不同类型。

例:

#include <iostream>  
using namespace std;  
template<class T1, class T2> 
void subtract(T1 x,T2 y)  
{  
  T1 res = x-y;  
  cout<<(res);  
    
}  
int main()  
{  

subtract<double, int>(3.5,2);  

return 0;  
}  

在上面的代码片段中,我们传递了一个float类型值作为T1的数据类型,并将int类型值作为T2的数据类型。

输出:

1.5

功能模板的重载

C++中函数模板的重载表明重载的函数将包含不同类型的参数。

让我们来看下面的示例,以了解模板中的函数重载。

#include <iostream>  
using namespace std;  
template<class T1> 
void area(T1 a)  
{  
  T1 res = a*a;
  cout<<"The area of Square:\n";
  cout<<(res);  
    
}  

template<class T1, class T2> 
void area(T1 l,T2 b)  
{  
  T1 res = l*b;  
   cout<<"\nThe area of Rectangle:\n";
  cout<<(res);  
    
} 

int main()  
{  

area(2);
area(3.5,1);

return 0;  
}  

在上面的代码片段中,我们重载了" area"函数,其中,我们通过将不同类型的参数传递给相应的函数来计算Square和Rectangle的面积。

输出:

The area of Square:
4
The area of Rectangle:
3.5

2. C++中的类模板

类模板通过传递与之关联的数据类型来帮助定义不同类型的类。

可以将其称为"通用类",因为该类的数据类型及其操作是在编译时通过传递与该类的函数关联的特定类型来确定的。

语法:

template<class type>  
class Class_name  
{  
//body 
}  

  • type是一个占位符/模板参数,它表示类的数据类型。

为了创建该类的实例,我们需要遵循以下语句:

Class_name<data_type> object_name;  

  • data_type:它是指与特定类相关联的数据类型。

例:

#include <iostream>  
using namespace std;  
template<class T>  
class Compute 
{ 
  public:
  T subtract(T x,T y)  
  {  
  T res = x-y;  
  return res;  
  }  
};  

int main()  
{  
  Compute<int> ob;
  cout<<"Subtraction function for Integer value as argument\n";
  cout<<"Result: "<<ob.subtract(10,5)<<"\n" ;
  return 0;  
}  

在上面的代码片段中,我们使用模板T传递数据

输出:

Subtraction function for Integer value as argument
Result: 5

类模板的多个参数

类模板可以具有多个参数,即一个类中可以有多个通用类型。

语法:

template<class T1, class T2, class T3, ......, class Tn>   
class Class_name  
{  
 //Body 
}  

例:

#include <iostream>  
using namespace std;  
template<class A, class B>  
class Compute   
{  
  A x;  
  B y;  
  public:  
     Compute(A i,B j)  
     {  
         x = i;  
         y = j;  
      }  
      void show()  
      {  
               cout <<x<<","<<y<<endl;  
      }  
    };  

    int main()  
   {  
         Compute<float,int> ob(5.5,2);  
         ob.show();  
         return 0;  
   }  

在上面的代码片段中,我们分别传递了两个通用类型A和B。

在创建类的实例时,我们将float和int传递为通用类型A和B的数据类型,并使用了一个Constructor类来初始化数据成员的值并显示出来。

输出:

5.5,2

模板中的非类型参数

类模板也可以包含多个参数。
这些参数可以是通用类型,也可以是非类型参数,例如常量,方法名称,字符串等。

语法:

template<class T, data_type var-name>  
class Class_name  
{  
      //Body            
};  

例:

#include <iostream>  
using namespace std;  
template<class T, int arg>  
class Compute  
{  public:
  T solve(T x,T y)  
 {  
     T res = x-y + arg;
     return res;     
  }  
};  

int main()  
{  
  Compute<int, 10> ob;
  
  cout<<"Result: "<<ob.solve(10,5)<<"\n" ;
  return 0;  
}  

其中我们将int类型的arg作为参数传递给类模板,并在主函数的函数调用期间传递了它的值。