首页 > 编程语言 > 详细

C++11 type_traits 之is_convertible源码分析

时间:2014-12-02 10:31:23      阅读:292      评论:0      收藏:0      [点我收藏+]

请看源码:

 template<typename _From, typename _To,
           bool = __or_<is_void<_From>, is_function<_To>,
                        is_array<_To>>::value>
    struct __is_convertible_helper
    { static constexpr bool value = is_void<_To>::value; };

  template<typename _From, typename _To>
    class __is_convertible_helper<_From, _To, false>
    : public __sfinae_types
    {
      template<typename _To1>
        static void __test_aux(_To1);

      template<typename _From1, typename _To1>
        static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
    __test(int);

      template<typename, typename>
        static __two __test(...);

    public:
      static constexpr bool value = sizeof(__test<_From, _To>(0)) == 1;
    };

  /// is_convertible
  template<typename _From, typename _To>
    struct is_convertible
    : public integral_constant<bool,
                   __is_convertible_helper<_From, _To>::value>
    { };

1.__is_convertible_helper是拥有三个模版参数的类模版,其中最后一个非类型模版参数有默认值。__or_<is_void<_From>, is_function<_To>, is_array<_To>>::value,只要其中任意一个为真,那么结果即为真。

2.__is_convertible_helper<_From, _To, false>__is_convertible_helper的偏特化,将bool的值设置为false,也就是说__or_<is_void<_From>, is_function<_To>, is_array<_To>>::value=false时,会转入此模版类。

3.对于为true的情况,is_void<_To>::value直接指示出类型是否可以转换。我们仔细分析一下:

   a.is_void<_From>::value为true,则能否转换结果为is_void<_To>::value,from为void,to也为void即可转换。

   b.如果is_array<_To>::value,is_function<_To>::value某个为true,则能否转换结果为is_void<_To>::value,在这里必然不能转换。

4.对于为false的情况,关键在于变长函数参数和sizeof表达式的妙用,如果没有这本书《C++设计新思维,泛型编程与设计模式之运用》我根本看不懂这些源码。

   a. template<typename _From1, typename _To1> static decltype(__test_aux<_To1>(std::declval<_From1>()), __one()) __test(int);

        __test()是一个函数,函数参数类型int,返回值由decltype推导而来,decltype里面是一个逗号表达式,如果__test_aux<_To1>(std::declval<_From1>())是有效的,那么decltype返回__one()的类型。

   b.如果表达式是无效的,则__two __test(...)被选择。在编译时,我们可以知道这两个函数一个返回类型__one,一个返回类型__two

   c.static constexpr bool value = sizeof(__test<_From, _To>(0)) == 1,调用函数,让编译器选择使用__test(int)还是__test(...),能进行类型转换就选择第一个,然后sizeof就返回值类型长度,指示出是否能进行转换。

C++11 type_traits 之is_convertible源码分析

原文:http://www.cnblogs.com/tangzhenqiang/p/4136728.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!