- C++ 基础
- C++ 首页
- C++ 概述
- C++ 环境设置
- C++ 基本语法
- C++ 注释
- C++ Hello World
- C++ 省略命名空间
- C++ 常量/字面量
- C++ 关键字
- C++ 标识符
- C++ 数据类型
- C++ 数值数据类型
- C++ 字符数据类型
- C++ 布尔数据类型
- C++ 变量类型
- C++ 变量作用域
- C++ 多个变量
- C++ 基本输入/输出
- C++ 修饰符类型
- C++ 存储类
- C++ 运算符
- C++ 数字
- C++ 枚举
- C++ 引用
- C++ 日期和时间
- C++ 控制语句
- C++ 决策
- C++ if 语句
- C++ if else 语句
- C++ 嵌套 if 语句
- C++ switch 语句
- C++ 嵌套 switch 语句
- C++ 循环类型
- C++ while 循环
- C++ for 循环
- C++ do while 循环
- C++ foreach 循环
- C++ 嵌套循环
- C++ break 语句
- C++ continue 语句
- C++ goto 语句
- C++ 构造函数
- C++ 构造函数和析构函数
- C++ 复制构造函数
C++ 模板
模板是泛型编程的基础,泛型编程是一种允许编写适用于不同数据类型的函数、类、算法和不同代码片段的编程风格。
模板是创建泛型类或函数的蓝图或公式。库容器(如迭代器和算法)是泛型编程的示例,并且是使用模板概念开发的。
每个容器(例如 vector)只有一个定义,但我们可以定义许多不同类型的 vector,例如 vector<int> 或 vector<string>。用于定义模板的两个关键字是 template 和 typename。
函数模板
函数模板定义了函数的蓝图,使函数能够在不同的数据类型上操作,而无需重写相同的逻辑。
语法
此处显示了模板函数定义的一般形式的语法:
template <typename identifier> function_declaration;
此处,“template”关键字声明泛型函数,“typename”关键字指定要用于参数的类型。
示例
以下是一个函数模板的示例,它返回两个值的较大值。
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
输出
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
类模板
类似地,类模板也定义了创建可用于任何数据类型的类的蓝图。
语法
template <class type> class class-name {
.
.
.
}
此处,type 是占位符类型名称,将在实例化类时指定。您可以通过使用逗号分隔的列表来定义多个泛型数据类型。
示例
以下是定义类 Stack<> 并实现泛型方法以将元素推入和弹出堆栈的示例:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return true if empty.
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem) {
// append copy of passed element
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop () {
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template <class T>
T Stack<T>::top () const {
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// return copy of last element
return elems.back();
}
int main() {
try {
Stack<int> intStack; // stack of ints
Stack<string> stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() <<endl;
// manipulate string stack
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
} catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
输出
7 hello Exception: Stack<>::pop(): empty stack
模板参数推导
模板参数推导是一项功能,它会自动推导(理解)传递给函数或类模板的参数的数据类型。编译器会为您推导出它们,而不是显式指定模板参数。
示例
让我们看看模板参数推导的示例:
template<typename T>
T add(T a, T b) {
return a + b;
}
int main() {
// The compiler deduces T as int
auto result1 = add(5, 3);
// The compiler deduces T as double
auto result2 = add(3.14, 2.86);
}
在此代码中,我们没有编写 add<int>(5,3) 或 add<double>(3.14, 2.86)。编译器会根据您提供的参数推导出类型。
函数模板参数推导
在 C++ 中,函数模板参数是一项功能,它允许编译器根据传递给函数的参数自动推导出模板参数的类型。
示例
这是一个函数模板参数推导的简单示例。
#include <iostream>
// Function template
template<typename T>
void printValue(T value) {
std::cout << value << std::endl;
}
int main() {
// Usage examples
printValue(42); // T is int
printValue("Hello"); // T is const char*
printValue(3.14159); // T is double
return 0;
}
输出
42 Hello 3.14159
类模板参数推导
C++ 中的类模板参数推导是一项功能,它使编译器能够在创建对象时从构造函数参数自动推断类模板的模板参数。
示例
这是一个类模板推导的基本实现。
#include <iostream>
template<typename T>
class Holder {
public:
Holder(T value) : data(value) {}
void show() const { std::cout << data << std::endl; }
private:
T data;
};
int main() {
Holder h1(42); // T deduced as int
Holder h2(3.14); // T deduced as double
Holder h3("Hello"); // T deduced as const char*
h1.show(); // Output: 42
h2.show(); // Output: 3.14
h3.show(); // Output: Hello
return 0;
}
输出
42 3.14 Hello
C++ 模板的优点
- 代码可重用性 - 模板使您能够编写适用于所有数据类型的通用代码,从而无需为每个所需的类型编写相同的代码。这通过减少代码重复来节省开发时间。
- 减少维护 - 更新模板并查看所有实例中的更改。在错误修复方面,修复一个错误并查看所有实例带来的好处,哪个更适用。
- 增强性能 - 模板实例化发生在编译时,减少了运行时错误。编译器会针对特定数据类型优化代码。
- 更好地组织代码 - 由于模板将算法逻辑与数据类型分开,因此有助于创建模块化代码,这在开发场景中更有利。它有助于减少搜索不同代码实现的次数。
广告