• <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>

            天下

            記錄修行的印記

            C++類中模板函數(shù)的特化

            C++類中模板函數(shù)的特化

            最近在使用在使用模板特化 寫一段程序時(shí)發(fā)現(xiàn)一個(gè)奇怪的問題,比如像如下代碼:

                 #include 
            <iostream>
            using namespace std;
            class CMyClass
            {
            public:
                 template 
            <typename T>
                 
            struct test
                 { 
                     T i;
                 };

                 template 
            <>
                 
            struct test<long>
                 {
                     unsigned 
            long i;
                 };
            };

            int main(void)
            {
                 CMyClass::test
            <int> test1;
                 CMyClass::test
            <long> test2;
                 CMyClass::test
            <char> test3;

                 cout 
            << "typeid(test1.i) is " << typeid(test1.i).name() << endl;
                 cout 
            << "typeid(test2.i) is " << typeid(test2.i).name() << endl;
                 cout 
            << "typeid(test3.i) is " << typeid(test3.i).name() << endl;

                 
            return 0;
            }

            這段代碼在Linux下的GCC 
            3.4.3下無法編譯通過,編譯時(shí)提示錯(cuò)誤:

            xxx.cpp:
            12: error: invalid explicit specialization before '>' token
            xxx.cpp:
            12: error: explicit specialization in non-namespace scope `class CMyClass'

            但在VC6和VC8下都可以編譯通過。

             

            后翻閱資料,發(fā)現(xiàn)有人提到,C
            ++標(biāo)準(zhǔn)中規(guī)定,嵌套類模板在類的定義中不允許被顯示特化聲明,只允許偏特化(“Explicit template specialization is forbidden for nested classes ”,“As partial template specialization is not forbidden ”),比如,這樣就可以:

                 
            #include 
            <iostream>
            using namespace std;

            class CMyClass
            {
            public:
                 template 
            <typename T, typename S = void>
                 
            struct test
                 {
                     T i;
                 };
                 template 
            <typename S>
                 
            struct test<long, S>
                 {
                     unsigned 
            long i;
                 };
            };
            int main(void)
            {
                 CMyClass::test
            <int> test1;
                 CMyClass::test
            <long> test2;
                 CMyClass::test
            <char> test3;

                 cout 
            << "typeid(test1.i) is " << typeid(test1.i).name() << endl;
                 cout 
            << "typeid(test2.i) is " << typeid(test2.i).name() << endl;
                 cout 
            << "typeid(test3.i) is " << typeid(test3.i).name() << endl;

                 
            return 0;

            }

            在上面這段代碼使用一個(gè)無用的模板參數(shù)來實(shí)現(xiàn)以偏特代替特化,從而化解了這個(gè)問題。至于為什么VC下能夠正常編譯,網(wǎng)上的資料說是VC不符合標(biāo)準(zhǔn) (“MSVC 
            is wrong in this case and g++ correct”),不過這點(diǎn)我尚未在C++標(biāo)準(zhǔn)中找到明文依據(jù)。

            但是這樣一來就有個(gè)問題,偏特化在VC6下是用BUG的,無法正常使用,也就是說出來的代碼將無法兼容VC6。對(duì)于VC6這樣落伍的編譯器,兼容它 是沒有太大的必要,但是回頭想想,難道要在定義嵌套類模板的特化,就不行了么?必須使用偏特化來代替么?C
            ++對(duì)此是如何規(guī)定的呢?翻閱相關(guān)資料后,我找 到了答案--要把特化的代碼寫在類定義的外面(要寫在namespace下),如第一段代碼應(yīng)該寫成這樣:

                 
            #include 
            <iostream>
            using namespace std;

            class CMyClass
            {
            public:
                 template 
            <typename T>
                 
            struct test
                 {
                     
            int i;
                 };
            };
            template 
            <>
            struct CMyClass::test<long>
            {
                 
            long i;
            };

            int main(void)
            {
                 CMyClass::test
            <int> test1;
                 CMyClass::test
            <long> test2;
                 CMyClass::test
            <char> test3;

                 cout 
            << "typeid(test1.i) is " << typeid(test1.i).name() << endl;
                 cout 
            << "typeid(test2.i) is " << typeid(test2.i).name() << endl;
                 cout 
            << "typeid(test3.i) is " << typeid(test3.i).name() << endl;

                 
            return 0;
            }

            這樣修改后,就可以在GCC下編譯通過了,同時(shí),VC6,VC8也都能編譯通過!

            總結(jié)一下吧:
            在C
            ++中,如果要對(duì)嵌套類模板進(jìn)行特化,則要么使用偏特化來替代特化(增加一個(gè)無用的模板參數(shù)),要么將 特化代碼放在類定義之外。

            同樣的,非模板函數(shù)具有最高的優(yōu)先權(quán)




            轉(zhuǎn)自:http://jeffreyloo.blog.163.com/blog/static/12176167020106171424608/

            posted on 2013-06-26 11:51 天下 閱讀(2546) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++C++模板

            <2012年1月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(4)

            隨筆分類(378)

            隨筆檔案(329)

            鏈接

            最新隨筆

            搜索

            最新評(píng)論

            久久婷婷五月综合97色一本一本 | 久久se精品一区二区影院| 伊人久久综合无码成人网| 久久久久亚洲av无码专区喷水| 色8久久人人97超碰香蕉987| 久久亚洲精品视频| 一级做a爰片久久毛片看看| 精品多毛少妇人妻AV免费久久| 国产午夜精品理论片久久影视 | 亚洲欧美一级久久精品| 久久亚洲精品人成综合网| 国产精品成人99久久久久| 亚洲国产精品无码久久久不卡| 久久久久中文字幕| 亚洲午夜久久久久久噜噜噜| 久久影院亚洲一区| 久久精品国产91久久麻豆自制| 国产精品一区二区久久精品涩爱| 国内精品久久久久影院优| 久久久久亚洲av成人网人人软件 | 精品999久久久久久中文字幕| 久久影视综合亚洲| 办公室久久精品| 久久久久成人精品无码中文字幕| 亚洲欧洲精品成人久久奇米网| 国产精品久久久久…| 无码AV波多野结衣久久| 国产99久久久国产精品小说| 久久久久一本毛久久久| 久久久久亚洲精品无码网址 | 久久精品中文字幕久久| 久久久久亚洲AV成人片| 亚洲精品无码久久久久久| 久久婷婷五月综合国产尤物app| 蜜臀久久99精品久久久久久| 久久激情五月丁香伊人| 国产福利电影一区二区三区久久老子无码午夜伦不 | 国产成人精品久久一区二区三区av| 久久福利青草精品资源站免费| 俺来也俺去啦久久综合网| 国产精品禁18久久久夂久|