• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            為什么不要特化函數模版

            在C++中有class templatesfunction templates,這兩種模版有很多區別,最重要的區別就是重載(overloading):
            普通的C++類不能重載,當然類模版也不能重載;相反,普通函數可以重載,函數模版也能重載。這再正常不過,看下面的代碼:

            1 // Example 1: Class vs. function template, and overloading
            2 //

            3 
            4 // A class template
            5 template<class T> class X { /*...*/ };      // (a)
            6 

            7 // A function template with two overloads
            8 template<class T> void f( T );              // (b)
            9 template<class T> void f( int, T, double ); // (c)
            10 

            像上面未特化的模板通常叫做base templates。當然,base templates能夠被特化,在特化這一點上
            class templatesfunction templates有很大的區別:一個class template 能夠被partially specialized and/or
            fully specialized,一個function template只能被fully specialized,但是由于function templates能夠重載我們可以通過重載來實現和partially specialized 相當的功能。下面的代碼說明了這些區別:

            1 // Example 1, continued: Specializing templates
            2 //

            3 
            4 // A partial specialization of (a) for pointer types
            5 template<class T> class X<T*> { /*...*/ };
            6 

            7 // A full specialization of (a) for int
            8 template<> class X<int> { /*...*/ };
            9 

            10 // A separate base template that overloads (b) and (c)
            11 //
            -- NOT a partial specialization of (b), because
            12 //
            there's no such thing as a partial specialization
            13 // of a function template!

            14 template<class T> void f( T* );             // (d)
            15 

            16 // A full specialization of (b) for int
            17 template<> void f<int>( int );              // (e)
            18 

            19 // A plain old function that happens to overload with
            20 //
            (b), (c), and (d) -- but not (e), which we'll
            21 // discuss in a moment

            22 void f( double );                           // (f)
            23 

            根據函數重載解析規則:

            1 // Example 1, continued: Overload resolution
            2 // 

            3  bool b;
            4 int
            i;
            5 double
            d;
            6 

            7 f( b );        // calls (b) with T = bool
            8 f( i, 42, d ); // calls (c) with T = int
            9 f( &i );       // calls (d) with T = int
            10 f( i );        // calls (e)
            11 f( d );        // calls (f)

            上面說的這些其實都是很簡單的情況,大多數人很容易就能明白,下面的才是容易讓人弄混的:

            1.考慮如下代碼:

            1 // Example 2: Explicit specialization
            2 // 

            3 template<class T> // (a) a base template
            4 void f( T );
            5 

            6 template<class T> // (b) a second base template, overloads (a)
            7 void f( T* );     //      (function templates can't be partially
            8                   //     specialized; they overload instead)

            9 
            10 template<>        // (c) explicit specialization of (b)
            11 void f<>(int* );
            12 

            13 // ...
            14 
            15 int * p;
            16 f( p );           // calls (c)

            最后一行的結果像大多數人所期望的一樣,問題是:為什么期望是這個結果?
            如果你期望的原因是錯誤的,接下來的一定會讓你好奇。也許你會說:"我為int*寫了一個特化版本,f(p)當然會調用c",不幸的是,這正是錯誤的原因!!!

            2.再考慮下面的代碼:

            1 // Example 3
            2 // 

            3 template<class T> // (a) same old base template as before
            4 void f( T );
            5 

            6 template<>        // (c) explicit specialization, this time of (a)
            7 void f<>(int* );
            8 

            9 template<class T> // (b) a second base template, overloads (a)
            10 void f( T* );
            11 

            12 // ...
            13 
            14 int * p;
            15 f( p );           //
            calls (b)! overload resolution ignores
            16                   //
            specializations and operates on the base
            17                   // function templates only

            如果這個結果讓你感到驚奇,那就對了!很多人都會感到驚奇!
            理解這個的關鍵是:Specializations don't overload,only the base templates overload.

            重載解析僅僅選擇base template(或者nontemplate function,如果有的話),只有當編譯器已經決定了哪個
            base template將會被選擇,編譯器才會繼續往下尋找適合的特化版本,如果找到了就使用那個特化版本。

            最后,應當避免特化函數模板,也要避免重載函數模板(nontemplate function的重載當然沒問題)。如果一定要這樣,可以使用如下方法模擬函數模板的偏特化:

            1 //base template class,
            2 template <class T>
            3  struct FuncImpl {
            4     //users, go ahead and specialize this

            5     static int apply(const T & t) {
            6         return 0
            ;
            7 
                }
            8 
            };
            9 

            10 //partial specialazation for int
            11 template <>
            12 struct FuncImpl<int> {
            13     static int apply(int
            t) {
            14         return 1
            ;
            15 
                }
            16 
            };
            17 

            18 //partial specialazation for T*
            19 template <class T>
            20     struct FuncImpl<T *> {
            21     static int apply(T *
            t) {
            22         return 2
            ;
            23 
                }
            24 
            };
            25 

            26 //users, don't touch this!
            27 template <class T>
            28 int func(const T & t) {
            29     return FuncImpl<T>
            ::apply(t);
            30 
            }
            31 

            32 int i = 10 , r;
            33 r = func('c'); //r = 0

            34 r = func(8); //r = 1
            35 r = func(&i); //r = 2

            posted on 2008-10-13 11:26 肥仔 閱讀(302) 評論(0)  編輯 收藏 引用 所屬分類: C++ 模板

            久久精品国产91久久麻豆自制| 91精品婷婷国产综合久久| 天天躁日日躁狠狠久久| 久久精品无码专区免费东京热| 999久久久国产精品| 亚洲国产成人久久一区久久| 欧美黑人激情性久久| 国内精品免费久久影院| 久久综合精品国产二区无码| 久久精品国产只有精品66| 亚洲综合伊人久久大杳蕉| Xx性欧美肥妇精品久久久久久 | 中文字幕久久精品无码| 丁香五月综合久久激情| 欧美黑人又粗又大久久久| 亚洲国产成人精品女人久久久 | 国产成人久久久精品二区三区| 国产精品中文久久久久久久| 久久线看观看精品香蕉国产| 囯产极品美女高潮无套久久久| 久久久久无码中| 国产精品欧美久久久久无广告| 国内精品久久久人妻中文字幕| 污污内射久久一区二区欧美日韩| 蜜桃麻豆www久久| 国产精品久久久久国产A级| 亚洲国产欧洲综合997久久| 欧美成人免费观看久久| 久久天天躁狠狠躁夜夜2020| 国产精久久一区二区三区| 俺来也俺去啦久久综合网| 久久精品人人做人人爽97| 日韩人妻无码精品久久久不卡| 久久精品国产免费观看三人同眠| 欧美精品丝袜久久久中文字幕| 久久99精品久久久久久噜噜| 国产视频久久| 狠狠色丁香婷婷久久综合| 久久亚洲精品成人无码网站| 国产成人久久精品一区二区三区| 亚洲伊人久久成综合人影院 |