模板的特化與偏特化

  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後面的尖括號中不帶任何內容;
  模板偏特化是指只給部分模板參數一個具體的類型,來實現這個模板。

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