别人没那么重要,我也没那么重要,好好活着,把能做的小事做好,够不到的东西就放弃,承认就好。做一个心情好能睡着的人,你所有事情都会在正轨上。

【C++】泛型编程-模板

1. 简介

  C++模板是一种支持泛型编程的机制,允许开发者定义使用任意类型作为输入的数据结构和函数。模板提供了一种编写具有类型无关性的代码的方法,这使得同一份代码可以用于不同的数据类型,而无需为每种类型重复编写代码。

  模板就是建立通用的模具,大大提高复用性。

模板的特点:

  • 模板不可以直接使用,它只是一个框架
  • 模板的通用并不是万能的

2. 函数模板

  C++中的函数模板是一种允许你定义一个使用任意类型作为参数的函数的方式。函数模板提供了一种编写类型无关代码的方法,使得同一份代码可以用于不同的数据类型。

2.1. 基本语法

1 template <typename T>
2 functionDeclaration;

2.2. 示例

 1 #include <iostream>
 2 
 3 // 函数模板定义
 4 template <typename T>
 5 T max(T a, T b) {
 6     return (a > b) ? a : b;
 7 }
 8 
 9 int main() {
10     int i = max(3, 5);      // 调用 int 类型的 max
11     double d = max(6.34, 5.8);  // 调用 double 类型的 max
12     std::cout << "i = " << i << ", d = " << d << std::endl;
13     return 0;
14 }

  在这个例子中,max 函数模板可以处理任何可以通过 > 运算符比较的类型。

2.3. 模板参数推断

  C++ 允许从函数参数中推断模板参数的类型,这被称为模板参数推断或自动推导:

1 template <typename T>
2 void print(T item) {
3     std::cout << item << std::endl;
4 }
5 
6 print(10);      // 推断出 T 为 int
7 print(3.14);    // 推断出 T 为 double
8 print("Hello"); // 推断出 T 为 const char*

2.4. 非类型模板参数

  除了类型参数,模板还可以接受非类型参数,如整数或指针:

1 template <typename T, int size>
2 class Array {
3     T data[size];
4     // ...
5 };

2.5. 模板特化

  模板特化是为特定类型或值提供模板定义的另一种形式的过程:

 1 template <typename T>
 2 T getDefaultValue() {
 3     return T();
 4 }
 5 
 6 template <>
 7 int getDefaultValue<int>() {
 8     return 0;
 9 }
10 
11 template <>
12 double getDefaultValue<double>() {
13     return 0.0;
14 }

  在这个例子中,我们为 getDefaultValue 函数提供了两个特化版本,分别对应 int 和 double 类型。

2.6. 注意

  • 函数模板在编译时实例化,这意味着编译器会为模板使用的具体类型生成代码。
  • 函数模板提供了一种编写灵活且可重用代码的方法,但也可能增加编译时间,因为模板实例化会生成更多的机器代码。
  • 函数模板是C++的一个强大特性,允许开发者编写类型无关的通用代码。
  • 函数模板是实现泛型编程的重要工具,它们使得同一份代码可以用于不同的数据类型,从而提高代码的复用性。

3. 类模板

  C++ 类模板是一种泛型编程工具,允许你定义一个类,其成员(包括数据成员和成员函数)可以使用任意类型。类模板提供了一种编写类型无关代码的方法,使得同一份代码可以用于不同的数据类型。

3.1. 基本语法

1 template <typename T>
2 class ClassName {
3     // ...
4 };

3.2. 示例

 1 #include <iostream>
 2 #include <string>
 3 
 4 // 类模板定义
 5 template <typename T>
 6 class Container {
 7 private:
 8     T data;
 9 public:
10     void setData(const T& d) {
11         data = d;
12     }
13     T getData() const {
14         return data;
15     }
16 };
17 
18 int main() {
19     Container<int> intContainer;
20     intContainer.setData(10);
21     std::cout << "int value: " << intContainer.getData() << std::endl;
22 
23     Container<std::string> stringContainer;
24     stringContainer.setData("Hello, World!");
25     std::cout << "string value: " << stringContainer.getData() << std::endl;
26 
27     return 0;
28 }

  这个例子中,Container 类模板可以处理任何类型的对象,包括内置类型(如 int)和用户定义类型(如 std::string)。

3.3. 模板参数推断

  C++ 允许从构造函数参数中推断模板参数的类型,这被称为模板参数推断:

1 template <typename T>
2 class Wrapper {
3 public:
4     T value;
5 };
6 
7 Wrapper<int> w1(42); // 推断出 T 为 int
8 Wrapper<std::string> w2("Hello"); // 推断出 T 为 std::string

3.4. 非类型模板参数

  除了类型参数,类模板还可以接受非类型参数,如整数或指针:

1 template <typename T, int size>
2 class Array {
3     T data[size];
4     // ...
5 };

3.5. 模板特化

  模板特化是为特定类型或值提供模板定义的另一种形式的过程:

 1 template <typename T>
 2 class MyClass {
 3 public:
 4     T member;
 5 };
 6 
 7 // 特化版本,针对 int 类型
 8 template <>
 9 class MyClass<int> {
10 public:
11     int member;
12     static int extra_member;
13 };
14 
15 int MyClass<int>::extra_member = 0;

  在这个例子中,我们为 MyClass 提供了一个特化版本,当模板参数类型为 int 时使用。

3.6. 注意

  • 类模板在编译时实例化,这意味着编译器会为模板使用的具体类型生成代码。
  • 类模板提供了一种编写灵活且可重用代码的方法,但也可能增加编译时间,因为模板实例化会生成更多的机器代码。
  • 类模板是C++的一个高级特性,需要对C++的类型系统有深入的理解。
  • 类模板是实现泛型编程的强大工具,它们允许开发者编写类型无关的通用代码,从而提高代码的复用性。

4. 总结

  • 模板代码在编译时实例化,这意味着编译器会为模板使用的具体类型生成代码。
  • 模板可以提高代码的复用性,但也可能增加编译时间,因为模板实例化会生成更多的机器代码。
  • 模板编程是C++的一个高级特性,需要对C++的类型系统有深入的理解。
  • C++模板是实现泛型编程的强大工具,它们允许开发者编写灵活且高效的代码。

 

时间:2024年4月29日

 

posted @ 2024-04-29 17:31  一路狂奔的乌龟  阅读(50)  评论(0)    收藏  举报
返回顶部