# C++ 模板

> 原文： [https://www.programiz.com/cpp-programming/templates](https://www.programiz.com/cpp-programming/templates)

#### 在本文中，您将学习 C++ 中的模板。 您将学习如何使用模板的功能进行通用编程。

模板是 C++ 的强大功能，可让您编写通用程序。 简而言之，您可以使用模板创建单个函数或类以使用不同的数据类型。

模板通常在较大的代码库中使用，以实现代码的可重用性和程序的灵活性。

模板的概念可以两种不同的方式使用：

*   函数模板
*   类模板

* * *

## 函数模板

函数模板的工作方式与普通[函数](/cpp-programming/function "C++ functions")类似，但有一个按键差异。

单个函数模板可以一次处理不同的数据类型，但是单个普通函数只能处理一组数据类型。

通常，如果需要对两种或更多种类型的数据执行相同的操作，则可以使用函数重载来创建具有所需函数声明的两个函数。

但是，更好的方法是使用函数模板，因为您可以执行较少的代码并维护代码来执行相同的任务。

* * *

### 如何声明函数模板？

函数模板以关键字`template`开头，后跟`< >`内的模板参数，然后是函数声明。

```cpp
template <class T>
T someFunction(T arg)
{
   ... .. ...
}
```

在上面的代码中，`T`是接受不同数据类型（`int`，`float`）的模板参数，而`class`是关键字。

您也可以使用关键字`typename`代替上面示例中的类。

将数据类型的参数传递给`someFunction( )`时，编译器将为给定数据类型生成`someFunction()`的新版本。

* * *

### 示例 1：查找最大数量的函数模板

**使用函数模板显示两个数字中最大的一个的程序。**

```cpp
// If two characters are passed to function template, character with larger ASCII value is displayed.

#include <iostream>
using namespace std;

// template function
template <class T>
T Large(T n1, T n2)
{
	return (n1 > n2) ? n1 : n2;
}

int main()
{
	int i1, i2;
	float f1, f2;
	char c1, c2;

	cout << "Enter two integers:\n";
	cin >> i1 >> i2;
	cout << Large(i1, i2) <<" is larger." << endl;

	cout << "\nEnter two floating-point numbers:\n";
	cin >> f1 >> f2;
	cout << Large(f1, f2) <<" is larger." << endl;

	cout << "\nEnter two characters:\n";
	cin >> c1 >> c2;
	cout << Large(c1, c2) << " has larger ASCII value.";

	return 0;
}
```

**输出**

```cpp
Enter two integers:
5
10
10 is larger.

Enter two floating-point numbers:
12.4
10.2
12.4 is larger.

Enter two characters:
z
Z
z has larger ASCII value. 
```

在上述程序中，定义了一个函数模板`Large()`，该模板接受数据类型为`T`的两个参数`n1`和`n2`。`T`表示参数可以是任何数据类型。

`Large()`函数使用简单的[条件操作](/cpp-programming/if-else "C++ if else")返回两个参数中的最大值。

在`main()`函数内部，声明了三种不同数据类型的变量：`int`，`float`和`char`。 然后将变量作为常规函数传递到`Large()`函数模板。

在运行时，将整数传递给模板函数时，编译器知道必须生成一个`Large()`函数来接受`int`参数，并且这样做。

同样，当传递浮点数据和`char`数据时，它知道自变量数据类型并相应地生成`Large()`函数。

这样，仅使用一个函数模板即可替换三个相同的常规函数​​，并使您的代码可维护。

* * *

### 示例 2：使用函数模板交换数据

**使用函数模板交换数据的程序。**

```cpp
#include <iostream>
using namespace std;

template <typename T>
void Swap(T &n1, T &n2)
{
	T temp;
	temp = n1;
	n1 = n2;
	n2 = temp;
}

int main()
{
	int i1 = 1, i2 = 2;
	float f1 = 1.1, f2 = 2.2;
	char c1 = 'a', c2 = 'b';

	cout << "Before passing data to function template.\n";
	cout << "i1 = " << i1 << "\ni2 = " << i2;
	cout << "\nf1 = " << f1 << "\nf2 = " << f2;
	cout << "\nc1 = " << c1 << "\nc2 = " << c2;

	Swap(i1, i2);
	Swap(f1, f2);
	Swap(c1, c2);

        cout << "\n\nAfter passing data to function template.\n";
	cout << "i1 = " << i1 << "\ni2 = " << i2;
	cout << "\nf1 = " << f1 << "\nf2 = " << f2;
	cout << "\nc1 = " << c1 << "\nc2 = " << c2;

	return 0;
} 
```

**输出**

```cpp
Before passing data to function template.
i1 = 1
i2 = 2
f1 = 1.1
f2 = 2.2
c1 = a
c2 = b

After passing data to function template.
i1 = 2
i2 = 1
f1 = 2.2
f2 = 1.1
c1 = b
c2 = a

```

在该程序中，不是通过传递值来调用函数，而是通过引用执行了[调用](/cpp-programming/pointers-function "C++ call by reference")。

`Swap()`函数模板接受两个参数，并通过引用交换它们。

* * *

## 类模板

与函数模板一样，您也可以为通用类操作创建类模板。

有时，您需要一个适用于所有类的类实现，只是所使用的数据类型不同。

通常，您需要为每种数据类型创建一个不同的类，或者在一个类中创建不同的成员变量和函数。

这将不必要地浪费您的代码库，并且将难以维护，因为更改是应该对所有类/函数执行一个类/函数。

但是，类模板使对所有数据类型重用相同的代码变得容易。

* * *

### 如何声明一个类模板？

```cpp
template <class T>
class className
{
   ... .. ...
public:
   T var;
   T someOperation(T arg);
   ... .. ...
};
```

在上面的声明中，`T`是模板参数，它是所使用数据类型的占位符。

在类体内，成员变量`var`和成员函数`someOperation()`均为`T`类型。

* * *

### 如何创建类模板对象？

要创建类模板对象，需要在创建时在`< >`中定义数据类型。

```cpp
className<dataType> classObject;

```

例如：

```cpp
className<int> classObject;
className<float> classObject;
className<string> classObject;

```

* * *

### 示例 3：使用类模板的简单计算器

程序使用类模板对两个数字进行加，减，乘和除运算

```cpp
#include <iostream>
using namespace std;

template <class T>
class Calculator
{
private:
	T num1, num2;

public:
	Calculator(T n1, T n2)
	{
		num1 = n1;
		num2 = n2;
	}

	void displayResult()
	{
		cout << "Numbers are: " << num1 << " and " << num2 << "." << endl;
		cout << "Addition is: " << add() << endl;
		cout << "Subtraction is: " << subtract() << endl;
		cout << "Product is: " << multiply() << endl;
		cout << "Division is: " << divide() << endl;
	}

	T add() { return num1 + num2; }

	T subtract() { return num1 - num2; }

	T multiply() { return num1 * num2; }

	T divide() { return num1 / num2; }
};

int main()
{
	Calculator<int> intCalc(2, 1);
	Calculator<float> floatCalc(2.4, 1.2);

	cout << "Int results:" << endl;
	intCalc.displayResult();

	cout << endl << "Float results:" << endl;
	floatCalc.displayResult();

	return 0;
}

```

**输出**

```cpp
Int results:
Numbers are: 2 and 1.
Addition is: 3
Subtraction is: 1
Product is: 2
Division is: 2

Float results:
Numbers are: 2.4 and 1.2.
Addition is: 3.6
Subtraction is: 1.2
Product is: 2.88
Division is: 2 

```

在上面的程序中，声明了一个类模板`Calculator`。

该类包含两个`T`类型的私有成员：`num1` & `num2`，以及用于初始化成员的构造器。

它还包含公共成员函数，用于计算数字的加法，减法，乘法和除法，这些数返回用户定义的数据类型的值。 同样，函数`displayResult()`将最终输出显示到屏幕上。

在`main()`函数中，为数据类型分别创建了两个不同的`Calculator`对象`intCalc`和`floatCalc`：`int`和`float`。 使用构造器初始化值。

请注意，在创建对象时我们使用`<int>`和`<float>`。 这些告诉编译器用于类创建的数据类型。

这将分别为`int`和`float`创建一个类定义，然后相应地使用它们。

然后，调用两个对象的`displayResult()`，它们执行计算器操作并显示输出。