C++11 模板元編程 - 模板的模板參數(shù)


上例中由于Stack類模板的聲明中第二個參數(shù)是一個類型(typename Container),所以我們通過Stack<int, std::deque<int>>定義一個具體的棧類型時,第二個參數(shù)傳遞std::deque<int>,而不能是std::deque。上述定義中我們一共把int寫了兩遍,而這種重復(fù)是一種必然的重復(fù)。

為了避免上述重復(fù),我們可以讓Stack的第二個參數(shù)直接是一個模板,而不再是一個具體類型。

template<typename T,
         template<typename> class Container = std::vector>
struct Stack
{
    void push(const T& elem)
    {
        elems.push_back(elem);
    }

    T pop()
    {
        if(empty()) throw std::out_of_range("Stack<>::pop: empty!");

        auto elem = elems.back();
        elems.pop_back();
        return elem;
    }

    bool empty() const
    {
        return elems.empty();
    }

private:
    Container<T> elems;
};

如上Stack類模板的第二個參數(shù)變?yōu)?code>template<typename> class Container,它的名字仍舊是Container,但是類型變?yōu)橐粋€模板,這個模板具有一個類型參數(shù)。由于Container自身的模板形參名字沒有被使用,所以我們可以省略。按照標(biāo)準(zhǔn)這里聲明Container前的關(guān)鍵字只能是class,不能是typename。最后,模板的模板參數(shù)也可以有默認(rèn)值,這里我們設(shè)置為std::vector

有了上面的定義,我們期望可以這樣使用Stack:Stack<int, std::deque> intStack,但編譯器卻給了我們一個教訓(xùn)。

std::deque類模板在stl庫中的定義有兩個類型參數(shù),第一個參數(shù)是元素類型,第二個參數(shù)是分配器allocator的類型。雖然std::deque的第二個類型參數(shù)有默認(rèn)值,但是當(dāng)編譯器使用std::deque替換Container時卻會嚴(yán)格匹配參數(shù),默認(rèn)值被忽略了。

我們修改Stack的定義如下:

template<typename T,
         template<typename Elem, typename Allocator = std::allocator<Elem>> class Container = std::vector>
struct Stack
{
    void push(const T& elem)
    {
        elems.push_back(elem);
    }

    T pop()
    {
        if(empty()) throw std::out_of_range("Stack<>::pop: empty!");

        auto elem = elems.back();
        elems.pop_back();
        return elem;
    }

    bool empty() const
    {
        return elems.empty();
    }

private:
    Container<T> elems;
};

現(xiàn)在Stack<int, std::deque> intStack可以編譯通過了!

可以看到模板的模板參數(shù)特性,可以讓類模板之間通過模板參數(shù)互相組合。如果我們將類模板比作C++編譯期的函數(shù),那么可以接受模板作為參數(shù)的類模板,就相當(dāng)于一個函數(shù)的入?yún)⑷耘f可以是函數(shù),這是后面我們會介紹到的高階函數(shù)的概念。


模板的特化

返回 C++11模板元編程 - 目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容