• 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 会有帮助吧。 还没有用过。

    我目前的水平主要还是自己推,不知道大牛们玩模板是不是和咱写程序一样轻松。。。  回复  更多评论
  • 相关阅读:
    C# WinForm 中 MessageBox的使用详解
    C#中MemoryStream类的介绍
    C#中String类的几个方法(IndexOf、LastIndexOf、Substring)
    C#ImageList和ListView的使用
    ListView的BeginUpdate()和EndUpdate()的用处
    C#中AppDomain.CurrentDomain.BaseDirectory及各种路径获取方法
    C#字符串比较方法
    C# ListView用法详解
    c#中枚举类型的定义与使用
    c#中的模态对话框和非模态对话框
  • 原文地址:https://www.cnblogs.com/cutepig/p/1400182.html
Copyright © 2020-2023  润新知