C++非類型模板參數


對於函數模板與類模板,模板參數並不局限於類型,普通值也可以作為模板參數。在基於類型參數的模板中,你定義了一些具體的細節來加以確定代碼,直到代碼被調用時這些細節才被真正的確定。但是在這里,我們面對的是這些細節是值,而不是類型,當要使用基於值的模板時,必須顯式地指定這些值,才能夠對模板進行實例化。

 本文地址: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];
}
stack4.h

實現代碼:

#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;
}
main

MAXSIZE是新加入的第二個模板參數,類型為int,它指定了數組最多可包含的棧元素的個數
同樣,我們可以為模板參數指定缺省值:

template<typename T = int, int MAXSIZE = 100>
class Stack {
    ...
};

非類型的函數模板參數

你也可以為函數模板定義非類型參數。例如:

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"初始化,是一個外部鏈接對象

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM