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(dot.gif);
 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(dot.gif);
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(dot.gif);
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)   编辑  收藏 引用
74452.html?webview=1
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值