使用数值型模板参数是有限制的,如:a> 变量不能作为模板参数;b> 浮点数不能作为模板参数;c> 类对象不能作为模板参数。其本质是模板参数是在编译阶段被处理的单元,因此在编译阶段必须准确无误的唯一确定。
下来我们用函数模板来实现一个面试题:用最高效的方法求 1+2+3+...+N 的值。
#include <iostream> #include <string> using namespace std; template < typename T, int N > void Func() { T a[N] = {0}; for(int i=0; i<N; i++) { a[N] = i + 1; } for(int i=0; i<N; i++) { cout << a[i] << endl; } } 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; }
我们通过用函数模板来实现递归的定义,递归的出口为它的完全特化为 1 时。下来我们来看看编译结果
我们看到已经实现了这个功能。下来我们再来实现数组类的模板
Array.h 源码
#ifndef _ARRAY_H_ #define _ARRAY_H_ template < typename T, int N > class Array { T m_array[N]; public: int length(); bool set(int index, T value); bool get(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>::set(int index, T value) { bool ret = (0 <= index) && (index < N); if( ret ) { m_array[index] = value; } return ret; } template < typename T, int N > bool Array<T, N>::get(int index, T& value) { bool ret = (0 <= index) && (index < N); if( ret ) { value = m_array[index]; } 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
Test.cpp 源码
#include <iostream> #include <string> #include "Array.h" using namespace std; int main() { Array<double, 5> ad; for(int i=0; i<ad.length(); i++) { ad[i] = i * i; } for(int i=0; i<ad.length(); i++) { cout << ad[i] << endl; } return 0; }
我们来看看编译结果
我们看到已经正确地实现了数组类的创建。下来我们再来完善下之前写的 IntArray 类。
HeapArray.h 源码
#ifndef _HEAPARRAY_H_ #define _HEAPARRAY_H_ template < typename T > class HeapArray { private: int m_length; T* m_pointer; HeapArray(int len); bool construct(); public: static HeapArray<T>* NewInstance(int length); int length(); bool get(int index, T& value); bool set(int index, T value); T& operator [] (int index); T operator [] (int index) const; HeapArray<T>& self(); ~HeapArray(); }; template < typename T > HeapArray<T>::HeapArray(int len) { m_length = len; } template < typename T > bool HeapArray<T>::construct() { m_pointer = new T[m_length]; return m_pointer != NULL; } template < typename T > HeapArray<T>* HeapArray<T>::NewInstance(int length) { HeapArray<T>* ret = new HeapArray<T>(length); if( !(ret && ret->construct()) ) { delete ret; ret = 0; } return ret; } template < typename T > int HeapArray<T>::length() { return m_length; } template < typename T > bool HeapArray<T>::get(int index, T& value) { bool ret = (0 <= index) && (index <= length()); if( ret ) { value = m_pointer[index]; } return ret; } template < typename T > bool HeapArray<T>::set(int index, T value) { bool ret = (0 <= index) && (index <= length()); if( ret ) { m_pointer[index] = value; } return ret; } template < typename T > T& HeapArray<T>::operator [] (int index) { return m_pointer[index]; } template < typename T > T HeapArray<T>::operator [] (int index) const { return m_pointer[index]; } template < typename T > HeapArray<T>& HeapArray<T>::self() { return *this; } template < typename T > HeapArray<T>::~HeapArray() { delete[] m_pointer; } #endif
Test.cpp 源码
#include <iostream> #include <string> #include "HeapArray.h" using namespace std; int main() { HeapArray<int>* pai = HeapArray<int>::NewInstance(10); if( pai != NULL ) { HeapArray<int>& ai = pai->self(); for(int i=0; i<ai.length(); i++) { ai[i] = i + 1; } for(int i=0; i<ai.length(); i++) { cout << ai[i] << endl; } } delete pai; return 0; }
我们编译下看看结果
我们再来试试 char 类型呢,打印 a 以后的 10 个字母
我们看到也已正确实现了,这便证明了我们写的数组类模板是能实现各种数据类型的。通过对数组类模板的学习,总结如下:1、模板参数可以是数值型参数;2、数组型模板参数必须在编译期间唯一确定;3、数组类模板是基于数值型模板参数实现的;4、数组类模板是简易的线性表数据结构。
欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。
原文地址:http://blog.51cto.com/12810168/2123381