對於函數模板與類模板,模板參數並不局限於類型,普通值也可以作為模板參數。在基於類型參數的模板中,你定義了一些具體的細節來加以確定代碼,直到代碼被調用時這些細節才被真正的確定。但是在這里,我們面對的是這些細節是值,而不是類型,當要使用基於值的模板時,必須顯式地指定這些值,才能夠對模板進行實例化。
本文地址:http://www.cnblogs.com/archimedes/p/cpp-template-type.html,轉載請注明源地址。
在上篇文章(C++類模板)中我們介紹了一個stack類模板作為例子,下面將看一個新版本的stack模板,來敘述本文將要介紹的特性:
非類型的類模板參數
創建類的頭文件

#include<stdexcept> #include<iostream> using namespace std; template<typename T, int MAXSIZE> class Stack{ private: T elems[MAXSIZE]; int numElems; public: Stack(); void push(T const&); void pop(); T top() const; bool empty() const { return numElems == 0; } bool full() const { return numElems == MAXSIZE; } }; template<typename T, int MAXSIZE> Stack<T, MAXSIZE>::Stack():numElems(0) {} template<typename T, int MAXSIZE> void Stack<T, MAXSIZE>::push(T const& elem) { if(numElems == MAXSIZE) { throw out_of_range("Stack<>::push(): stack is full"); } elems[numElems] = elem; ++numElems; } template<typename T, int MAXSIZE> void Stack<T, MAXSIZE>::pop() { if(numElems <= 0) { throw out_of_range("Stack<>::pop(): stack is full"); } --numElems; } template<typename T, int MAXSIZE> T Stack<T, MAXSIZE>::top() const { if(numElems <= 0) { throw out_of_range("Stack<>::top(): stack is full"); } return elems[numElems - 1]; }
實現代碼:

#include<iostream> #include<vector> #include<deque> #include<stdexcept> #include<string> #include<cstdlib> #include "stack4.h" using namespace std; int main() { try { Stack<int, 20> int20Stack; Stack<int, 40> int40Stack; Stack<string, 40> stringStack; int20Stack.push(7); cout<<int20Stack.top()<<endl; int20Stack.pop(); stringStack.push("hello"); cout<<stringStack.top()<<endl; stringStack.pop(); stringStack.pop(); } catch(exception const& ex) { cerr<<"Exception: "<<ex.what()<<endl; //return EXIT_FAILURE; } cin.get(); return 0; }
MAXSIZE是新加入的第二個模板參數,類型為int,它指定了數組最多可包含的棧元素的個數
同樣,我們可以為模板參數指定缺省值:
非類型的函數模板參數
你也可以為函數模板定義非類型參數。例如:
template<typename T, int VAL> T addValue(T const& x) { return x + VAL: }
借助於STL,可以傳遞這個函數模板的實例化給集中的每一個元素,讓他們都增加一個整數值:
std::transform(source.begin(), source.end(), dest.begin(), (int(*)(int const&))addValue<int, 5>);
非類型模板參數的限制
非類型模板參數是有限制的,通常而言,它們可以是常整數(包括枚舉值)或者指向外部鏈接對象的指針。
浮點數和類對象是不允許作為非類型模板參數的:
template<double VAT> double process(double v) //error { return V * VAT; } template<string name> //error class MyClass { ... };
另外,你也不能使用全局指針作為模板參數:
template<char const* name> class MyClass{ ... }; char const* s = "hello"; MyClass<s> x; //s是一個指向內部連接對象的指針
但是你可以這樣使用:
template<char const* name> class MyClass { ... }; extern char const s[] = "hello"; MyClass<s> x; //OK
全局字符數組s由"hello"初始化,是一個外部鏈接對象