boost::trait::is_reference 的研究与修改
生活随笔
收集整理的這篇文章主要介紹了
boost::trait::is_reference 的研究与修改
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
boost::trait::is_reference 的研究與修改
http://www.cppblog.com/yindf/archive/2009/02/20/74452.html
先看看boost的實現吧。
?1?template<typename?_T>
?2?struct?wapper
?3?{};
?4?template?<typename?_T>
?5?_T&(*?fun1(wapper<_T>?t))();
?6?true_type?fun1();
?7?
?8?class?true_type{};
?9?class?false_type
10?{
11?????char?c[8];
12?};
13?
14?template<typename?_T>
15?true_type?fun2(_T&(*)());
16?false_type?fun2();
17?
18?template<typename?_T>
19?struct?is_reference
20?{
21?????static?const?bool?value?=?sizeof(fun2(fun1(wapper<_T>())))?==?sizeof(false_type);
22?};
就是上面這個樣子,我做了一下簡化,更容易理解。
下面是我的實現版本,最后再解釋。
?1?template<typename?_T>
?2?class?is_reference
?3?{
?4?????template<typename?_T>
?5?????struct?wapper
?6?????{};
?7?
?8?????class?true_type{};
?9?????class?false_type
10?????{
11?????????char?c[8];
12?????};
13?
14?????template?<typename?_T>
15?????static?_T&?fun1(wapper<_T>);
16?????static?true_type?fun1();
17?
18?????template<typename?_T>
19?????static?true_type?fun2(_T);
20?????static?false_type?fun2(true_type);
21?public:
22?????static?const?bool?value?=?sizeof(fun2(fun1(wapper<_T>())))?==?sizeof(false_type);
23?};
用法如下:
1?bool?res1?=?is_reference<char>::value;???//res1?==?false
2?bool?res2?=?is_reference<char&>::value;??//res2?==?true
函數參數會自動去掉引用比如:
template<_T> void fun(_T a);
無論任何時候,_T總是非引用類型。
但是不讓函數通過函數參數直接推導模板參數的類型,就給函數參數加一個間接層wapper,
類模板不會自動去掉引用,所以配合函數模板可以保證得到原來的類型。
?
template<_T> void fun(wapper<_T> a);
這時候,_T 就可能是引用類型了。因為c++不支持引用的引用,當模板函數中要用到引用的引用的時候,模板函數就會推導失敗。
即,只要在函數fun的參數或者返回值里面含有_T&的話,fun就會推導失敗。從而編譯器會選擇 true_type fun(...);
由于參數已經被用于推導模板參數,所以只能在返回類型中含有_T&,從而利用函數重載而區分引用和非引用。
如果直接返回_T&類型,后面必須要定義只接受true_type類型參數的函數進行區分,因為_T&肯定是引用類型,所以后面接受
false_type fun2(true_type)的函數會被選擇。
但是遇到is_reference<true_type>::value怎么辦,我把他們都放到私有域了,永遠不會看到的,搞定。
boost::trait中返回函數指針的解法也OK。因為char永遠不可能成功匹配函數指針。
此方法的關鍵在于編譯器選擇重載函數的先后順序。
而boost::trait中的方法是char永遠不能轉化成一個函數指針,從而選擇不同重載版本。
解釋完畢。
posted on 2009-02-20 21:44 尹東斐 閱讀(835) 評論(3) ?編輯?收藏 引用
FeedBack: #?re: boost::trait::is_reference 的研究與修改 2009-02-20 21:48 | 發生地方
不錯,不錯??回復??更多評論
?? #?re: boost::trait::is_reference 的研究與修改[未登錄] 2009-02-21 09:27 | jans2002
高手,總覺得模板很玄乎,也沒有好的調試手段??回復??更多評論
?? #?re: boost::trait::is_reference 的研究與修改 2009-02-21 10:35 | 尹東斐
@jans2002
模板現在是不好調試,不過好像VC 10的 intellisence 會有幫助吧。 還沒有用過。
我目前的水平主要還是自己推,不知道大牛們玩模板是不是和咱寫程序一樣輕松。。。??回復??更多評論
http://www.cppblog.com/yindf/archive/2009/02/20/74452.html
先看看boost的實現吧。
?1?template<typename?_T>
?2?struct?wapper
?3?{};
?4?template?<typename?_T>
?5?_T&(*?fun1(wapper<_T>?t))();
?6?true_type?fun1();
?7?
?8?class?true_type{};
?9?class?false_type
10?{
11?????char?c[8];
12?};
13?
14?template<typename?_T>
15?true_type?fun2(_T&(*)());
16?false_type?fun2();
17?
18?template<typename?_T>
19?struct?is_reference
20?{
21?????static?const?bool?value?=?sizeof(fun2(fun1(wapper<_T>())))?==?sizeof(false_type);
22?};
就是上面這個樣子,我做了一下簡化,更容易理解。
下面是我的實現版本,最后再解釋。
?1?template<typename?_T>
?2?class?is_reference
?3?{
?4?????template<typename?_T>
?5?????struct?wapper
?6?????{};
?7?
?8?????class?true_type{};
?9?????class?false_type
10?????{
11?????????char?c[8];
12?????};
13?
14?????template?<typename?_T>
15?????static?_T&?fun1(wapper<_T>);
16?????static?true_type?fun1();
17?
18?????template<typename?_T>
19?????static?true_type?fun2(_T);
20?????static?false_type?fun2(true_type);
21?public:
22?????static?const?bool?value?=?sizeof(fun2(fun1(wapper<_T>())))?==?sizeof(false_type);
23?};
用法如下:
1?bool?res1?=?is_reference<char>::value;???//res1?==?false
2?bool?res2?=?is_reference<char&>::value;??//res2?==?true
函數參數會自動去掉引用比如:
template<_T> void fun(_T a);
無論任何時候,_T總是非引用類型。
但是不讓函數通過函數參數直接推導模板參數的類型,就給函數參數加一個間接層wapper,
類模板不會自動去掉引用,所以配合函數模板可以保證得到原來的類型。
?
template<_T> void fun(wapper<_T> a);
這時候,_T 就可能是引用類型了。因為c++不支持引用的引用,當模板函數中要用到引用的引用的時候,模板函數就會推導失敗。
即,只要在函數fun的參數或者返回值里面含有_T&的話,fun就會推導失敗。從而編譯器會選擇 true_type fun(...);
由于參數已經被用于推導模板參數,所以只能在返回類型中含有_T&,從而利用函數重載而區分引用和非引用。
如果直接返回_T&類型,后面必須要定義只接受true_type類型參數的函數進行區分,因為_T&肯定是引用類型,所以后面接受
false_type fun2(true_type)的函數會被選擇。
但是遇到is_reference<true_type>::value怎么辦,我把他們都放到私有域了,永遠不會看到的,搞定。
boost::trait中返回函數指針的解法也OK。因為char永遠不可能成功匹配函數指針。
此方法的關鍵在于編譯器選擇重載函數的先后順序。
而boost::trait中的方法是char永遠不能轉化成一個函數指針,從而選擇不同重載版本。
解釋完畢。
posted on 2009-02-20 21:44 尹東斐 閱讀(835) 評論(3) ?編輯?收藏 引用
FeedBack: #?re: boost::trait::is_reference 的研究與修改 2009-02-20 21:48 | 發生地方
不錯,不錯??回復??更多評論
?? #?re: boost::trait::is_reference 的研究與修改[未登錄] 2009-02-21 09:27 | jans2002
高手,總覺得模板很玄乎,也沒有好的調試手段??回復??更多評論
?? #?re: boost::trait::is_reference 的研究與修改 2009-02-21 10:35 | 尹東斐
@jans2002
模板現在是不好調試,不過好像VC 10的 intellisence 會有幫助吧。 還沒有用過。
我目前的水平主要還是自己推,不知道大牛們玩模板是不是和咱寫程序一樣輕松。。。??回復??更多評論
轉載于:https://www.cnblogs.com/cutepig/archive/2009/02/28/1400182.html
總結
以上是生活随笔為你收集整理的boost::trait::is_reference 的研究与修改的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过传入的栏目编号找出并返回当前栏目编号
- 下一篇: C# 工厂模式 简单入门