模板参数可以是数值型参数(非类型参数)
template <typename T,int N>
void func()
{
T a[N]; //使用模板参数的数值型参数定义局部数组
}
func<double,10>();
数值型模板参数的限制
-变量不能作为模板参数
-浮点数不能作为模板参数
-类对象不能作为模板参数
…
本质:
模板参数是再编译阶段被处理的单元,因此,在编译阶段必须准确无误的唯一确定
例子:
#include <iostream>
#include <string>
using namespace std;
template <typename T,int N>//template <typename T,double N>会报错,因为浮点数不能作为模板参数
void func()
{
T a[N] = {0};
for(int i=0;i<N;i++)
{
a[i] = i;
}
for(int i =0;i<N;i++)
{
cout<<a[i]<<endl;
}
}
int main()
{
func<int,10>();//int a =10,fun<int,a>()会报错,因为变量不能作为模板参数
return 0;
}
使用类模板和类模板特例化实现"1+2+…N"
#include <string>
#include <iostream>
using namespace std;
template <int N>
class Sum
{
public:
static const int Value = Sum<N-1>::Value + N;
};
template <>
class Sum<1>
{
public:
static const int Value = 1;
};
int main()
{
cout << "1 + 2 + 3 + ... + 10 = " << Sum<10>::Value<<endl;
cout << "1 + 2 + 3 + ... + 100 = " << Sum<100>::Value<<endl;
return 0;
}
结果:
sice@sice:~$ ./a.out
1 + 2 + 3 + ... + 10 = 55
1 + 2 + 3 + ... + 100 = 5050
因为模板在编译的时候就已经确定了,所以大大的提高了代码效率
现在我们来实现一个数组模板类
1.初体会
a.h
我们之前说过类模板要放在头文件中定义
#ifndef _A_H_
#define _A_H_
template <typename T,int N>
class Array
{
T m_array[N];
public:
int length();
bool getA(int index,T& value);
bool setA(int index,T value);
T& operator[](int index);
T operator[](int index)const;
virtual ~Array();
};
template <typename T,int N>
int Array<T,N>::length()
{
return N;
}
template <typename T,int N>
bool Array<T,N>::getA(int index,T& value)
{
bool ret = (index>=0)&&(index<N);
if(ret)
{
value = m_array[index];
}
return ret;
}
template <typename T,int N>
bool Array<T,N>::setA(int index,T value)
{
bool ret = (index>=0)&&(index<N);
if(ret)
{
m_array[index] = value;
}
return ret;
}
template <typename T,int N>
T& Array<T,N>::operator[](int index)
{
return m_array[index];
}
template
< typename T, int N >
T Array<T, N>::operator[] (int index) const
{
return m_array[index];
}
template
< typename T, int N >
Array<T, N>::~Array()
{
}
#endif
a.c
#include <string>
#include <iostream>
#include "a.h"
using namespace std;
int main()
{
Array<int,10>a;
for(int i=0;i<a.length();i++)
{
a[i] = i*i;
}
for(int i=0;i<a.length();i++)
{
cout<<a[i]<<endl;
}
cout<<endl;
return 0;
}
结果:
sice@sice:~$ ./a.out
0
1
4
9
16
25
36
49
64
81
2.发挥类模板的优势,用以支持不同类型的数组
修改a.cpp
#include <string>
#include <iostream>
#include "a.h"
using namespace std;
int main()
{
Array<int,10>a;
for(int i=0;i<a.length();i++)
{
a[i] = i*i;
}
for(int i=0;i<a.length();i++)
{
cout<<a[i]<<endl;
}
cout<<endl;
Array<char,10>b;
for(char i=0;i<b.length();i++)
{
b[i] = i+'a';
}
for(char i=0;i<b.length();i++)
{
cout<<b[i]<<endl;
}
cout<<endl;
return 0;
}
结果:
1
4
9
16
25
36
49
64
81
a
b
c
d
e
f
g
h
i
j
如果我们想使用数组时我们就可以使用这个数组类模板,这就是代码复用!
通过例子我们可以知道模板参数可以时数值型参数,数值型模板参数必须
在编译期间唯一确定,数组类模板是基于数值型模板参数实现的,数组类模
板是简易的线性表数据结构