zoukankan      html  css  js  c++  java
  • 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 会有帮助吧。 还没有用过。

    我目前的水平主要还是自己推,不知道大牛们玩模板是不是和咱写程序一样轻松。。。  回复  更多评论
  • 相关阅读:
    input上传mp3格式文件,预览并且获取时间
    jquery 页面input上传图后显示
    将String类型的字符串拼接成以逗号分隔的字符输出
    layui select多选下拉显示 以及回显
    input输入框只能输入数字和英文逗号
    电脑开机右下角有小金锁,并且提示一分钟后重启电脑
    修改tomcat控制台的标题
    VC防止程序被多次运行 互斥体方法
    VC中遍历进程并获取进程信息
    VC中遍历目标进程中的模块
  • 原文地址:https://www.cnblogs.com/cutepig/p/1400182.html
Copyright © 2011-2022 走看看