C++ 模板
C++模板是C++中添加的一项强大的功能。它允许您定义通用类和通用函数,从而提供对通用编程的支持。通用编程是一种技术,其中将通用类型用作算法中的参数,以使它们适用于各种数据类型。
模板可以用两种方式表示:
- 函数模板
- 类模板
函数模板:
我们可以为函数定义一个模板。例如,如果我们有一个add()函数,我们可以为添加int、float或double类型的值创建add函数的版本。
类模板:
我们可以为类定义一个模板。例如,可以创建一个数组类的模板,该模板可以接受各种类型的数组,如int数组、float数组或double数组。
函数模板
- 通用函数使用函数模板的概念。通用函数定义了一组可应用于各种类型数据的操作。
- 函数将操作的数据类型取决于作为参数传递的数据类型。
- 例如,快速排序算法使用通用函数实现,它可以实现对整数数组或浮点数数组的排序。
- 使用关键字template创建通用函数。该模板定义函数将执行的操作。
函数模板的语法
template < class Ttype> ret_type func_name(parameter_list)
{
// body of function.
}
Ttype :这是函数使用的数据类型的占位符名称。它在函数定义中使用。它只是一个占位符,编译器将自动将此占位符替换为实际的数据类型。
class :class关键字用于在模板声明中指定一个通用类型。
让我们看一个函数模板的简单示例:
#include <iostream>
using namespace std;
template<class T> T add(T &a,T &b)
{
T result = a+b;
return result;
}
int main()
{
int i =2;
int j =3;
float m = 2.3;
float n = 1.2;
cout<<"Addition of i and j is :"<<add(i,j);
cout<<'\n';
cout<<"Addition of m and n is :"<<add(m,n);
return 0;
}
输出:
Addition of i and j is :5
Addition of m and n is :3.5
在上面的示例中,我们创建了一个函数模板,可以对任何类型进行加法运算,无论它是整数、浮点数还是双精度数。
具有多个参数的函数模板
我们可以使用多个通用类型在模板函数中,使用逗号来分隔列表。
语法
template<class T1, class T2,.....>
return_type function_name (arguments of type T1, T2....)
{
// body of function.
}
在上面的语法中,我们看到模板函数可以接受不同类型的任意数量的参数。 让我们看一个简单的示例:
#include <iostream>
using namespace std;
template<class X,class Y> void fun(X a,Y b)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(15,12.3);
return 0;
}
输出:
Value of a is : 15
Value of b is : 12.3
在上面的示例中,我们在模板函数中使用了两个通用类型,即X和Y。
重载函数模板
我们可以重载通用函数,这意味着重载的模板函数可以在参数列表上有所不同。
让我们通过一个简单的示例来理解这个概念:
#include <iostream>
using namespace std;
template<class X> void fun(X a)
{
std::cout << "Value of a is : " <<a<< std::endl;
}
template<class X,class Y> void fun(X b ,Y c)
{
std::cout << "Value of b is : " <<b<< std::endl;
std::cout << "Value of c is : " <<c<< std::endl;
}
int main()
{
fun(10);
fun(20,30.5);
return 0;
}
输出:
Value of a is : 10
Value of b is : 20
Value of c is : 30.5
在上面的示例中,fun()函数的模板被重载了。
泛型函数的限制
泛型函数对于函数的所有版本执行相同的操作,只是数据类型不同。让我们看一个简单的重载函数的示例,这个函数不能被泛型函数替代,因为两个函数具有不同的功能。
让我们通过一个简单的示例来理解:
#include <iostream>
using namespace std;
void fun(double a)
{
cout<<"value of a is : "<<a<<'\n';
}
void fun(int b)
{
if(b%2==0)
{
cout<<"Number is even";
}
else
{
cout<<"Number is odd";
}
}
int main()
{
fun(4.6);
fun(6);
return 0;
}
输出:
value of a is : 4.6
Number is even
在上面的示例中,我们重载了普通函数。由于这两个函数具有不同的功能,我们无法重载通用函数。第一个函数显示数值,第二个函数判断一个数是否为偶数。
类模板
类模板 的定义与函数模板类似。当一个类使用模板的概念时,这个类被称为泛型类。
语法
template<class Ttype>
class class_name
{
.
.
}
Ttype 是一个占位符名称,将在实例化类时确定。我们可以使用逗号分隔的列表定义多个泛型数据类型。Ttype可以在类体内使用。
现在,我们创建一个类的实例
class_name<type> ob;
class_name 值 :这是类的名称。
type 值 :这是类所操作的数据类型。
ob 值 :这是对象的名称。
让我们看一个简单的示例:
#include <iostream>
using namespace std;
template<class T>
class A
{
public:
T num1 = 5;
T num2 = 6;
void add()
{
std::cout << "Addition of num1 and num2 : " << num1+num2<<std::endl;
}
};
int main()
{
A<int> d;
d.add();
return 0;
}
输出:
Addition of num1 and num2 : 11
在上面的示例中,我们为类A创建了一个模板。在main()方法中,我们创建了类A的一个实例,命名为’d’。
具有多个参数的类模板
我们可以在类模板中使用多个泛型数据类型,每个泛型数据类型用逗号分隔。
语法
template<class T1, class T2, ......>
class class_name
{
// Body of the class.
}
让我们来看一个简单的示例,当类模板包含两个通用数据类型时。
#include <iostream>
using namespace std;
template<class T1, class T2>
class A
{
T1 a;
T2 b;
public:
A(T1 x,T2 y)
{
a = x;
b = y;
}
void display()
{
std::cout << "Values of a and b are : " << a<<" ,"<<b<<std::endl;
}
};
int main()
{
A<int,float> d(5,6.5);
d.display();
return 0;
}
输出:
Values of a and b are : 5,6.5
非类型模板参数
模板可以包含多个参数,我们还可以使用非类型参数。除了类型T参数之外,我们还可以使用其他类型的参数,比如字符串、函数名、常量表达式和内置类型。 让我们看下面的示例:
template<class T, int size>
class array
{
T arr[size]; // automatic array initialization.
};
在上述情况下,非类型模板参数是size,因此模板将数组的大小作为参数提供。
当创建类的对象时,可以指定参数:
array<int, 15> t1; // array of 15 integers.
array<float, 10> t2; // array of 10 floats.
array<char, 4> t3; // array of 4 chars.
让我们来看一个非类型模板参数的简单示例。
#include <iostream>
using namespace std;
template<class T, int size>
class A
{
public:
T arr[size];
void insert()
{
int i =1;
for (int j=0;j<size;j++)
{
arr[j] = i;
i++;
}
}
void display()
{
for(int i=0;i<size;i++)
{
std::cout << arr[i] << " ";
}
}
};
int main()
{
A<int,10> t1;
t1.insert();
t1.display();
return 0;
}
输出 :
1 2 3 4 5 6 7 8 9 10
在上面的示例中,创建了一个包含nontype模板参数(即size)的类模板。它在创建类的对象时指定。
要记住的重点
- C++支持一个强大的特性,即模板来实现泛型编程的概念。
- 模板允许我们创建一组类或函数来处理不同的数据类型。
- 模板类和函数消除了不同数据类型的代码重复,从而使开发更容易和更快速。
- 在类和函数模板中都可以使用多个参数。
- 模板函数也可以重载。
- 我们还可以使用非类型参数,例如内置或派生的数据类型作为模板参数。