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(boost::trait::is_reference 的研究与修改);
 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(boost::trait::is_reference 的研究与修改);
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(boost::trait::is_reference 的研究与修改);
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)  编辑 收藏 引用
boost::trait::is_reference 的研究与修改
FeedBack:
# re: boost::trait::is_reference 的研究与修改
2009-02-20 21:48 | 更多评论
  

相关文章:

  • 2021-04-23
  • 2022-02-09
  • 2022-12-23
  • 2021-12-08
  • 2021-12-26
  • 2021-07-07
  • 2022-01-04
  • 2021-11-19
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-14
  • 2022-12-23
  • 2022-12-23
  • 2021-07-14
  • 2022-12-23
相关资源
相似解决方案