特化和偏特化

Partial Template Specialization能夠讓你在模板(Template)的所有可能的實體中特化出一組子集.

  1.模板的特化(template specialization):

    例如,定義如下的一個模板:
    template<class Window, class Controller>
    class Widget
    {
      ... 泛化實現代碼 ...
    };
    然後你可以像下面那樣明確地加以特化:
    template<>    //注意:template後面的尖括號中不帶任何內容;
    class Widget<ModalDialog, MyController>
    {
      ... 特化實現代碼 ...
    };
    其中ModalDialog和MyController是你自己另外定義的類;有了這個Widget的特化定義之後,如果你以後定義了Widget<ModalDialog, MyController>對象時,編譯器就會使用上述的特化定義,如果定義了其它泛型對象,那麼編譯器就是用原本的泛化定義;這就是模板的特化.

  2.Partial Template Specialization(模板偏特化)

從英文單詞可看出意思爲:模板部分物化."偏"實在不是一個明智的譯法,就像偏導數一樣,非得看定義才能明白,完全沒采用中文本意來翻譯.

模板特化是通過"給模板中的所有模板參數一個具體的類"的方式來實現的.而模板偏特化則是通過"給模板中的部分模板參數以具體的類,而留下剩餘的模板參數仍然使用原來的泛化定義"的方式來實現的;
    比如,就上面的Widget類模板的定義來說,有時候想針對任意的Window來搭配一個特定的MyController類特化Widget,這個時候就需要使用模板偏特化機制了.下面的Widget類模板就是Widget的偏特化定義:
    template<class Window>                        //仍然使用原來的泛化定義;
    class Widget<Window, MyController>            //MyController是具體的類,是特化定義;
    {
      ... 偏特化實現代碼 ...
    };
    這就是一個偏特化定義;一個MyController類可以搭配任意一種Window.
    通常在一個類模板的偏特化定義中,你只會特化某些模板參數而留下其它泛化參數.當你在程序中具體實現上述類模板的時,編譯器會試着找出最匹配的模板定義.這個尋找過程十分複雜精細,允許你以富有創意的方式來進行偏特化.例如,假設你有一個Button類模板,它有一個模板參數,那麼,你不但可以拿任意的Window搭配特定的MyController來特化Widget,還可以拿任意Button搭配特定的MyController來偏特化Widget:
    template<class ButtonArg>
    class Widget<Button<ButtonArg>, MyController>    //使用任意Button搭配具體的類MyContorller
    {
      ... 偏特化實現代碼 ...
    };
    模板的偏特化能力很強大.當你實例化一個模板時,編譯器會把目前存在的偏特化模板和全特化模板做比較,並找出其中最合適、最匹配的實現.這樣,靈活性就很大.但是不幸的是,
模板的偏特化機制不能用在函數身上,不論成員函數還是非成員函數.

  注意:
  1.雖然你可以全特化類模板中的成員函數,但是你不能偏特化他們;
  2.你不能偏特化命名空間級別(namespace-level)的函數(non-member).最接近"命名空間級別模板函數"的偏特化機制就是函數重載,那就意味着你對"函數參數"(而非返回值類型或內部所用類型)有很精緻的特化能力;
  3.特化或全特化時,template後面的尖括號中不帶任何內容;

  總結:
模板特化/全特化是指給每一個模板參數一個具體的類型,以具體實現這個模板,而且template後面的尖括號中不帶任何內容;

模板偏特化是指只給部分模板參數一個具體的類型,來實現這個模板;


附:模板特化,全特化,偏特化,全部特化,部分特化的含義

這幾個名詞真是把人搞混了(是因爲有的著作,甚至名著以訛傳訛),我最近整理了以下,看看大家的意見如何。

模板特化:任何針對模板參數進一步進行條件限制設計的特化版本。《泛型思維》

全特化就是全部特化,即針對所有的模板參數進行特化。《c++ primer》
偏特化就是部分特化,即針對部分模板參數進行特化。《c++ primer》

全特化偏特化的定義不是很嚴格,所以有的時候不容易讓人理解。

舉例如下:
template<class U,class T>
class C{};
全特化:
template<>
class C<int,char>{};
偏特化:
template<class U>
class C<U,int>{};
大家應該對上面的例子應該沒有什麼異議吧。

再看下面的一個例子:
template<class T,class U>
class C<T*,U*>{};
這屬於全特化還是偏特化呢?一般大部分人都認爲是偏特化,但是按照上面的定義似乎應該是全特化(所有的模板參數都特化了呀)。

我覺得沒有必要在名詞上作口舌之爭,全特化也好,偏特化也好,只要我們掌握它的意義即可。折中的來看,我認爲就可以稱之爲模板特化,畢竟它符合模板特化的含義。

順便說一下:《c++ primer》這本書沒有很好的說明全特化偏特化的含義,造成很多的歧義,我對這個問題也是迷茫了好久。

規範的原文是這樣的:

The standard term explicit specialization refers to a language feature that we call full specialization instead. It provides an implementation for a template with template parameters that are fully substituted: No template parameters remain. Class templates and function templates can be fully specialized. So can members of class templates that may be defined outside the body of a class definition (i.e., member functions, nested classes, and static data members).


原文地址:http://blog.csdn.net/weiqubo/article/details/7197483

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章