閱讀368 返回首頁    go 阿裏雲 go 技術社區[雲棲]


c++學習筆記之成員模板

任意類(模板或者是飛模板)可以擁有類模板或函數模板的成員,這種成員成為成員模板,成員模板不能為虛。成員模板的一個例子是標準容器的assign成員,接受兩個迭代器的assign版本使用模板形參表示其迭代器形參的類型。另一個例子就是接受兩個迭代器的容器構造函數。
1 定義成員模板
模板成員聲明看起來像任意模板的聲明一樣。
template <class Type> class Queue{
    public:
        template <class It>Queue(It beg,It end){
            copy_elems(beg,end);
        }
        template <class Iter> void assign(Iter,Iter);
    private:
        template <class Iter> void copy_elems(Iter,Iter);
};

template <class Type> template <class Iter>
void Queue<Type>::assign(Iter beg,Iter end){
    //destroy();
    copy_elems(beg,end);
}

template <class Type> template <class Iter>
void Queue<Type>::copy_elems(Iter beg,Iter end){
    while(beg != end){
        push(*beg);
        ++beg;
    }
}
成員聲明的開頭是自己的模板形參表。構造函數和assign函數各有一個模板類型形參,這些函數使用這些類型形參作為其函數形參的類型,他們函數

形參指明要複製元素範圍的迭代器。


2 在類外定義成員模板
在類模板作用域外部定義成員模板的時候,那必須包含兩個模板形參表:
template <class Type> template <class Iter>
void Queue<Type>::assign(Iter beg,Iter end){
    //destroy();
    copy_elems(beg,end);
}

當成員模板時類模板的成員時,它的定義必須包含類模板形參以及自己的模板形參。
首先是類模板形參表,後麵接著是自己模板形參表。
assign函數定義的開頭為:
template <class Type> template <class Iter>
第一個模板形參表template <class Type>為類模板的,第二個模板形參表template <class Iter>是成員模板的。
3 成員模板的實例化
成員模板隻有在程序使用時才實例化。類模板的成員模板的實例化要比類模板的普通成員函數的實例化要複雜一些。
成員模板有兩種模板形參:(1)由類定義的(2)由成員模板本身定義的
類模板形參由調用函數的對象的類型確定,成員定義的模板形參的行為與普通函數模板一樣。這些形參都通過常規模版實參推斷確定。
short a[4] = {0,3,6,9};
    Queue<int> qi(a,a+4);
    vector<int> vi(a,a+4);
    qi.assign(vi.begin(),vi.end());

因為所構造的是Queue<int>類型的對象,我怕們知道編譯器將為Queue<int>實例化基於迭代器構造函數。該構造函數本身模版形參的類型由編譯器根據a和a+4的類型推斷,而該類型為short指針。因此,qi的定義實例化:
void Queue<int>::Queue(short *,short *);
對assign的調用將實例化qi的成員。qi具有Queue<int>類型,因此,這個調用將實例化名為assign的Queue<int>成員。該函數為函數模版,想起他任意的函數模版一樣,編譯器從傳給調用者的實參推斷assign的模版實參,推斷得到的類型是vector<int>::iterator,這個調用實例化:
void Queue<int>::assign(vector<int>::iterator,vector<int>::iterator);

最後更新:2017-04-03 12:56:23

  上一篇:go 2013年度ARM芯片圖形性能跑分橫向對比
  下一篇:go 預處理指令