C++模板詳解(三):參數化聲明詳解

在前兩節中(C++模板詳解(一)C++模板詳解(二)),咱們瞭解了函數模板和類模板的基本概念和使用方法。在這篇博文裏,咱們主要來詳細地闡述一下"模板的參數聲明"這個話題,而且也談及了函數模板和類模板相結合的使用方式和一些注意事項。html

1、函數模板做爲普通類和模板類的成員函數

函數模板能夠做爲普通類和模板類的成員函數。下面的這份代碼片斷演示了這一點:函數

template<typename T1>
class List
{
public:
    // 位於模板類中的成員函數模板定義:
    template<typename T2>           
    List(const List<T2>& other);    
    
    // 錯誤的寫法:不能夠是虛函數。
    template<typename T1>
    virtual void func(T1&& t)
    {
    }
};

// #1: 在類的外部定義上面的構造函數。
template<typename T1>
template<typename T2>
List<T1>::List(const List<T2>& other)
{
    //...
}

class Collection
{
    // 位於普通類內部的成員函數模板定義:
    template<typename T>
    T* alloc()
    {
        //...
    }
    
    // 錯誤的寫法:不能夠是虛函數。
    template<typename T>
    virtual void func(T&& t)
    {
    }
};

這份代碼展現出了不少的概念。code

  • 不管是普通類仍是模板類,其中的成員函數或是模板成員函數均可之內聯地定義在類中,或是定義在類的外部。在外部定義的成員函數模板能夠具備多個模板參數子句:一個子句做用於該模板自身,其它子句做用於外圍的類模板,其順序是從最外圍的類模板開始,依次到達內部模板。htm

  • 成員函數模板不能夠是虛函數。這是由於,實現虛函數須要使用一個固定大小的虛函數表,每一個虛函數都對應虛函數表的一個入口。然而,成員函數模板的實例化個數,要等到整個程序都編譯完成時才能肯定,這就和"虛函數表的大小是固定的"發生了衝突。因此,成員函數模板不能夠是虛函數。blog

2、模板類能夠被嵌套定義在普通類或者模板類中

模板類的定義也是能夠嵌套的。例以下面這份示例代碼:get

// 示例1:模板類能夠被嵌套定義在模板類中。
template<typename T1>
class List
{
    // 定義並實現。
    template<typename T2>
    class Node1
    {
    };
    
    // 定義。
    template<typename T2>
    class Node2;
};

// 外部實現。
template<typename T1>
template<typename T2>
class List<T1>::Node2
{

};

// 示例2:模板類能夠被嵌套定義在普通類中
class Shell
{
    // 定義並實現。
    template<typename T>
    class Inner1
    {
    };
    
    // 定義。
    template<typename T>
    class Inner2;
};

// 外部實現。
template<typename T>
class Shell::Inner2
{
};

相似於成員函數的類外實現,內部類的具體實現也一樣能夠被放到類外進行,它們的書寫規則和模板成員函數幾乎相同。io

3、函數模板聲明中的默認參數

函數模板一樣能夠在聲明中提供缺省參數:編譯

template<typename T>
void report(const Stack<T>& stack, int number = 10);

template<typename T>
void fill(const Array<T>& arr, const T& value = T());

因爲和普通函數的缺省參數功能類似,具體的注意事項能夠直接參看:C++函數詳解模板

相關文章
相關標籤/搜索