青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

#ant

The dreams in which I'm dying are the best I've ever had...

為什么不要特化函數模版

Overloading vs. Specialization

在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 2007-08-30 13:55 螞蟻終結者 閱讀(4189) 評論(4)  編輯 收藏 引用 所屬分類: C++

Feedback

# re: 為什么不要特化函數模版 2007-08-30 16:54 minidxer

不錯  回復  更多評論   

# re: 為什么不要特化函數模版 2007-08-31 09:01 calmman

不錯!  回復  更多評論   

# re: 為什么不要特化函數模版 2007-09-03 13:16 ymmol

如果那個特化函數有交代清楚,那就沒那么多問題了:
template<>
void f<int>(int arg){
//...
}

template<>
void f<int *>(int *arg){
//...
}

在調用時寫清楚也會少些疑惑:
int ia=1;
f<int>(ia);
f<int *>(&ia);
所以我覺得重載或特化都可以,只要你寫清楚了,都沒事  回復  更多評論   

# re: 為什么不要特化函數模版 2007-09-03 17:08 螞蟻終結者

@ymmol
是啊,不過有像我這樣懶的程序員,習慣了將參數推導交給編譯器,也習慣了make_pair類似的寫法。  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲裸体视频| 国产欧美日本一区视频| 99re热这里只有精品视频| 久久综合色综合88| 另类激情亚洲| 亚洲国产精品久久久久| 美日韩精品免费| 欧美国产乱视频| 亚洲理论在线| 亚洲一区二区三区在线观看视频| 亚洲男人天堂2024| 久久青草福利网站| 欧美韩日视频| 国产精品综合不卡av| 永久久久久久| 在线视频欧美日韩精品| 午夜在线成人av| 你懂的国产精品永久在线| 亚洲人妖在线| 欧美自拍偷拍| 欧美视频在线一区二区三区| 国产一区二区日韩精品欧美精品| 亚洲第一在线综合在线| 亚洲天堂免费在线观看视频| 久久电影一区| 日韩视频一区二区三区在线播放免费观看| 一区二区三区视频观看| 久久手机免费观看| 欧美午夜国产| 亚洲精品在线观看视频| 久久久久国产成人精品亚洲午夜| 亚洲欧洲一区| 久久精品国产久精国产爱| 欧美午夜在线视频| 亚洲精品免费在线观看| 久久伊人亚洲| 亚洲欧美日韩国产一区二区| 欧美日韩在线大尺度| 亚洲午夜一区| 国产一区二区三区网站| 中文久久精品| 亚洲高清精品中出| 久久精品国产第一区二区三区| 欧美日韩亚洲天堂| 亚洲日本电影在线| 欧美本精品男人aⅴ天堂| 午夜精品区一区二区三| 国产精品福利影院| 在线视频亚洲一区| 亚洲全部视频| 欧美国产国产综合| 亚洲激情图片小说视频| 久久久免费观看视频| 亚洲自拍偷拍一区| 国产精品激情| 亚洲欧美日韩成人高清在线一区| 亚洲美女网站| 欧美视频手机在线| 亚洲网站在线观看| 亚洲美女黄色| 欧美日韩一区二区三区四区五区| 日韩视频在线一区| 亚洲精品女av网站| 久久亚洲综合色一区二区三区| 国产自产高清不卡| 另类人畜视频在线| 久久亚洲免费| 亚洲美女少妇无套啪啪呻吟| 亚洲国产日本| 欧美日韩国产成人在线观看| 一区二区欧美视频| 中日韩男男gay无套 | 亚洲视频精选在线| 欧美午夜一区二区福利视频| 亚洲专区免费| 香蕉成人啪国产精品视频综合网| 国产三级精品三级| 老牛嫩草一区二区三区日本| 久久躁日日躁aaaaxxxx| 91久久夜色精品国产网站| 亚洲国产精品成人综合| 欧美日产一区二区三区在线观看| 亚洲私人黄色宅男| 欧美亚洲一区二区在线| 伊人久久综合97精品| 亚洲国产精品成人综合| 国产精品久久久久国产精品日日| 欧美制服丝袜| 欧美成人免费在线| 午夜精品久久久99热福利| 久久久国产精品亚洲一区| 亚洲麻豆国产自偷在线| 午夜精品999| 亚洲九九爱视频| 性xx色xx综合久久久xx| 亚洲激情在线观看| 亚洲欧美国产毛片在线| 亚洲精品中文字幕有码专区| 久久一二三国产| 亚洲免费大片| 香蕉成人久久| 日韩亚洲欧美高清| 久久精品国产第一区二区三区最新章节| 亚洲人成小说网站色在线| 亚洲欧美日韩网| 在线视频亚洲一区| 麻豆成人av| 久久久视频精品| 国产精品成人观看视频国产奇米| 欧美成人免费网| 国产一区观看| 亚洲一区久久久| 在线一区二区日韩| 免费观看30秒视频久久| 久久福利影视| 国产精品亚洲а∨天堂免在线| 亚洲精品少妇网址| 91久久精品日日躁夜夜躁欧美| 亚洲欧美亚洲| 午夜精品一区二区三区四区| 欧美福利精品| 欧美激情一区在线观看| 狠狠色狠狠色综合人人| 亚洲欧美精品中文字幕在线| 在线视频欧美日韩| 欧美日本亚洲韩国国产| 欧美激情第五页| 亚洲高清在线视频| 久久综合色综合88| 看片网站欧美日韩| 一色屋精品视频免费看| 欧美在线视频观看| 欧美一区二区三区播放老司机| 欧美三级午夜理伦三级中文幕 | 国产亚洲在线| 性久久久久久久| 久久久国产一区二区三区| 国产精品自拍网站| 欧美一级免费视频| 久久露脸国产精品| 影音先锋久久久| 久久综合伊人77777麻豆| 麻豆精品视频在线观看视频| 伊人久久婷婷色综合98网| 久久免费视频网| 亚洲成在人线av| 一本久久综合| 国产精品一区二区黑丝| 欧美中文在线字幕| 欧美阿v一级看视频| 99re国产精品| 国产精品日韩精品欧美精品| 亚洲欧美中文日韩在线| 麻豆精品网站| 99国产精品国产精品毛片| 欧美日韩一区二区三区四区五区| 亚洲性人人天天夜夜摸| 久久天天狠狠| 亚洲狼人精品一区二区三区| 欧美日韩四区| 欧美一区二区精品| 亚洲国产精品一区二区第一页| 在线视频日韩| 精品91免费| 国产精品一卡二卡| 樱桃国产成人精品视频| 免费毛片一区二区三区久久久| 亚洲黄网站黄| 午夜视频一区二区| 伊人久久大香线蕉综合热线| 欧美精品福利视频| 午夜精品久久久久99热蜜桃导演| 麻豆国产精品777777在线| 亚洲视频在线观看| 狠狠色狠狠色综合日日五| 欧美男人的天堂| 午夜久久黄色| 亚洲激情视频网站| 久久久久国产精品一区| 日韩亚洲欧美一区| 韩国三级电影久久久久久| 欧美日韩成人| 久久亚洲综合色| 亚洲欧美春色| 亚洲精品久久久久久下一站| 久久久在线视频| 亚洲小视频在线| 亚洲狠狠婷婷| 韩日精品在线| 国产精品伊人日日| 欧美日韩美女在线| 免费亚洲电影| 久久精品1区| 亚洲淫性视频| 在线视频欧美日韩精品| 91久久夜色精品国产九色| 老司机久久99久久精品播放免费 | 亚洲欧美日韩精品久久奇米色影视| 在线视频国产日韩| 国产视频一区二区三区在线观看|