C++模板深度解析

2022/6/17 5:50:28

本文主要是介绍C++模板深度解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一.函数模板的使用

泛型编程函数模板会自动类型推导调用,也可以显示类型调用。

1 int a = 0;
2 int b = 1;
3  
4 Swap(a,b);          //自动推导
5  
6 float c = 2;
7 float d = 3;
8  
9 Swap<float>(c, d);  //显示调用
 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 template < typename T >
 7 void Swap(T& a, T& b)
 8 {
 9     T c = a;
10     a = b;
11     b = c;
12 }
13  
14 template < typename T >
15 void Sort(T a[], int len)    //选择排序
16 {
17     for(int i=0; i<len; i++)
18     {
19         for(int j=i; j<len; j++)    
20         {
21             if( a[i] > a[j] )
22             {
23                 Swap(a[i], a[j]);
24             }
25         }
26     }
27 }
28  
29 template < typename T >
30 void Println(T a[], int len)    //打印数组元素数值
31 {
32     for(int i=0; i<len; i++)
33     {
34         cout << a[i] << ", ";
35     }
36     
37     cout << endl;
38 }
39  
40 int main()
41 {
42     int a[5] = {5, 3, 2, 4, 1};
43     
44     Println(a, 5);
45     Sort(a, 5);
46     Println(a, 5);
47     
48     string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"};
49     
50     Println(s, 5);
51     Sort(s, 5);
52     Println(s, 5);
53     
54     return 0;
55 }
1 5, 3, 2, 4, 1,
2 1, 2, 3, 4, 5,
3 Java, C++, Pascal, Ruby, Basic,
4 Basic, C++, Java, Pascal, Ruby,

多参数函数模板:无法自动推导返回值类型,可以从左向右部分指定类型参数,函数模板中的返回值类型必须显示指定。

1 // T1 = int, T2 = double, T3 = double
2 int r1 = Add<int>(0.5, 0.8);    //部分指定类型
3  
4 // T1 = int, T2 = float, T3 = double
5 int r2 = Add<int, float>(0.5, 0.8);    //部分指定类型,编译器根据实参0.8推导double
6  
7 // T1 = int, T2 = float, T3 = float
8 int r3 = Add<int, float, float>(0.5, 0.8);    //显示声明
 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 template 
 7 < typename T1, typename T2, typename T3 >
 8 T1 Add(T2 a, T3 b)
 9 {
10     return static_cast<T1>(a + b);
11 }
12  
13  
14 int main()
15 {
16     // T1 = int, T2 = double, T3 = double
17     int r1 = Add<int>(0.5, 0.8);
18  
19     // T1 = double, T2 = float, T3 = double
20     double r2 = Add<double, float>(0.5, 0.8);
21  
22     // T1 = float, T2 = float, T3 = float
23     float r3 = Add<float, float, float>(0.5, 0.8);
24  
25     cout << "r1 = " << r1 << endl;     // r1 = 1
26     cout << "r2 = " << r2 << endl;     // r2 = 1.3
27     cout << "r3 = " << r3 << endl;     // r3 = 1.3
28     
29     return 0;
30 }

结果:

1 r1 = 1      //函数返回值是int类型
2 r2 = 1.3    //函数返回值是double类型
3 r3 = 1.3    //函数返回值是float类型

重载函数模板:函数模板可以像普通函数一样被重载。

 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 template < typename T >
 7 T Max(T a, T b)    //模板函数——求ab谁大(重载)
 8 {
 9     cout << "T Max(T a, T b)" << endl;
10     
11     return a > b ? a : b;
12 }
13  
14 int Max(int a, int b)    //普通函数——求ab谁大
15 {
16     cout << "int Max(int a, int b)" << endl;
17     
18     return a > b ? a : b;
19 }
20  
21 template < typename T >
22 T Max(T a, T b, T c)    //函数模板——求abc中谁大(重载)
23 {
24     cout << "T Max(T a, T b, T c)" << endl;
25     
26     return Max(Max(a, b), c);    //2次模板调用
27 }
28 //3个Max函数有重载关系,也能进行函数重载
29  
30 int main()
31 {
32     int a = 1;
33     int b = 2;
34     //匹配的很好
35     cout << Max(a, b) << endl;                   // 普通函数 Max(int, int)
36     //提醒编译器优先使用
37     cout << Max<>(a, b) << endl;                 // 函数模板 Max<int>(int, int)
38     //匹配不好,用函数模板
39     cout << Max(3.0, 4.0) << endl;               // 函数模板 Max<double>(double, double)
40     //3个参数
41     cout << Max(5.0, 6.0, 7.0) << endl;          // 函数模板 Max<double>(double, double, double)
42     //这个例子好,有点迷惑人!'a'迷惑人,表现形式误解成char型
43     cout << Max('a', 100) << endl;               // 普通函数 Max(int, int)
44     
45     return 0;
46 }

结果:

 1 int Max(int a, int b)
 2 2
 3 T Max(T a, T b)
 4 2
 5 T Max(T a, T b)
 6 4
 7 T Max(T a, T b, T c)    
 8 T Max(T a, T b)    
 9 T Max(T a, T b)    
10 7
11 int Max(int a, int b)    
12 100    

二.类模板的使用

类模板注意点:只能显示指定具体类型,无法自动推导。

1 template < typename T >
2 class Operator
3 {
4 public:
5     T op(T a, T b);
6 };
1 Operator<int> op1;
2 Operator<string> op2;
3 int i = op1.op(1,2);
4 string s = op2.op("D.T.","Software");

类模板的工程应用:

类模板必须在头文件中定义,类模板不能分开实现在不同的文件中,类模板外部定义的成员函数需要加上模板<>声明。

Operator.h:

 1 #ifndef _OPERATOR_H_
 2 #define _OPERATOR_H_
 3  
 4 template < typename T >
 5 class Operator
 6 {
 7 public:
 8     T add(T a, T b);    //函数声明
 9     T minus(T a, T b);
10     T multiply(T a, T b);
11     T divide(T a, T b);
12 };
13  
14 template < typename T >    //模板<>声明
15 T Operator<T>::add(T a, T b)
16 {
17     return a + b;
18 }
19  
20 template < typename T >
21 T Operator<T>::minus(T a, T b)
22 {
23     return a - b;
24 }
25  
26 template < typename T >
27 T Operator<T>::multiply(T a, T b)
28 {
29     return a * b;
30 }
31  
32 template < typename T >
33 T Operator<T>::divide(T a, T b)
34 {
35     return a / b;
36 }
37  
38 #endif

Operator.cpp:

 1 #include <iostream>
 2 #include <string>
 3 #include "Operator.h"
 4  
 5 using namespace std;
 6  
 7 int main()
 8 {
 9     Operator<int> op1;    //显示声明模板
10     
11     cout << op1.add(1, 2) << endl;        //3
12     cout << op1.multiply(4, 5) << endl;   //20
13     cout << op1.minus(5, 6) << endl;      //-1
14     cout << op1.divide(10, 5) << endl;    //2
15     
16     return 0;
17 }

结果:

1 3
2 20
3 -1
4 2

 



这篇关于C++模板深度解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程