重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
1,预备知识:
我们提供的服务有:成都网站制作、网站建设、微信公众号开发、网站优化、网站认证、修水ssl等。为超过千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的修水网站制作公司
1,模板参数可以是数值型参数(非类型参数):
1,代码示例:
1 template
2 void func()
3 {
4 T a[N]; // 使用模板参数定义局部数组;
5 }
6
7 func(); // 使用模板时,数值型参数必须是常量,不能是变量;
2,数值型模板参数的限制:
1,变量不能作为模板参数;
1,是变量的话就不满足准确确定的这个本质;
2,浮点数不能作为模板参数;
1,浮点数本身不精确;
3,类对象不能作为模板参数;
1,类对象编译时不能唯一确定的,同变量一样;
3,数值型参数本质:模板参数是在编译阶段被处理的单元,因此,在编译阶段必须准确无误的唯一确定;
2,有趣的面试题:
1,用你觉得最高效的方法求 1 + 2 + 3 + ... + N 的值;
1,等差数列和的方式;
2,见下面实例;
3,数值型模板参数编程实验:
1 #include
2 #include
3
4 using namespace std;
5
6 /* 验证上面的预备知识 */
7 template
8 < typename T, int N > // 这里用成 double 后,编译器显示:error: 'double' is not a valid type for a template constant parameter
9 void func()
10 {
11 T a[N] = {0};
12
13 for(int i=0; i
14 {
15 a[i] = i;
16 }
17
18 for(int i=0; i
19 {
20 cout << a[i] << endl;
21 }
22 }
23
24 /* 用最高效的方法验证从 1 加到 n 的和;不用循环和等差数列求和公式 */
25 template
26 < int N >
27 class Sum
28 {
29 public:
30 // static const int VALUE = 0; // static 后是想定义常量,被 static 修饰后要么放入符号表、要么放到全局数据区; 这个时候 VALUE 已经确定了值,所以直接进入符号表(符号表存储在哪里呢);又因为 VALUE 被 static 修饰了,所以 VALUE 被放入全局数据区;
31 static const int VALUE = Sum::VALUE + N; // 递归定义
32 };
33
34 /* 定义上述模板类的特化实现,实现递归出口 */
35 template
36 < >
37 class Sum < 1 >
38 {
39 public:
40 static const int VALUE = 1;
41 };
42
43 int main()
44 {
45 func(); // 打印 0 到 9 这十个数字;这里如果模板参数类型为 double,编译器显示:error: no matching function for call to 'func()';
46
47 int a = 10;
48 func(); // 在这一行编译器显示:
49 // error: 'a' cannot appear in a constant-expression
50 // error: no matching function for call to 'func()'
51
52 cout << "1 + 2 + 3 + ... + 10 = " << Sum<10>::VALUE << endl; // 55;这里没有加减乘除法,也没有函数调用和循环,这里VALUE 是常量,并在编译的时候已经确定,这里效率是最高的;
53 cout << "1 + 2 + 3 + ... + 100 = " << Sum<100>::VALUE << endl; // 5050
54
55 return 0;
56 }
1,这里的相加求和是在编译器编译程序的时候完成的,编译完程序后,要求的和的值已经确定,在运行的时候,就直接可以访问这个值,不需要做任何的运算和循环,因此效率最高;
2,这个最高效的求和依赖了模板技术、模板特化技术、数值型模板参数技术;
3,可以举一反三,得到更多高效的程序写法;
4,数组模板类编程实验:
1,Array.h 文件:
1 #ifndef _ARRAY_H_ // 防止多次包含头文件;
2 #define _ARRAY_H_
3
4 template
5 < typename T, int N > // 数组元素的类型和大小;
6 class Array
7 {
8 T m_array[N]; // 定义一个实际的数组;
9 public:
10 int length();
11 bool set(int index, T value);
12 bool get(int index, T& value);
13 T& operator[] (int index);
14 T operator[] (int index) const; // 数组类对象有可能是 const 对象,这个时候就只能调用 const 函数,所以要定义这个;const 函数只能返回值,不能返回引用;
15 virtual ~Array(); // 有可能被继承
16 };
17
18 /* 模板类要放在一个文件中,所以实现在下面实现 */
19
20 template
21 < typename T, int N >
22 int Array::length()
23 {
24 return N;
25 }
26
27 template
28 < typename T, int N >
29 bool Array::set(int index, T value)
30 {
31 bool ret = (0 <= index) && (index < N);
32
33 if( ret )
34 {
35 m_array[index] = value;
36 }
37
38 return ret;
39 }
40
41 template
42 < typename T, int N >
43 bool Array::get(int index, T& value)
44 {
45 bool ret = (0 <= index) && (index < N);
46
47 if( ret )
48 {
49 value = m_array[index];
50 }
51无锡妇科费用 http://www.wxbhnkyy39.com/
52 return ret;
53 }
54
55 template
56 < typename T, int N >
57 T& Array::operator[] (int index)
58 {
59 return m_array[index];
60 }
61
62 template
63 < typename T, int N >
64 T Array::operator[] (int index) const
65 {
66 return m_array[index];
67 }
68
69 template
70 < typename T, int N >
71 Array::~Array()
72 {
73
74 }
75
76 #endif
5,小结:
1,模板参数可以是数值型参数;
2,数值型模板参数必须在编译期间唯一确定;
3,数组类模板是基于数值型模板参数实现的;
4,数组类模板是简易的线性表数据结构;