zoukankan      html  css  js  c++  java
  • 十分钟让你对C++ Traits大彻大悟

    最近和一个朋友闲聊的时候他对我说一个人对C++的理解很多种境界,朋友不是个喜欢吹牛的人,于是听他细说,觉得很是有道理。

    想写一篇C++ traits方面的文章已经有一段时间了,但是说实话traits这项技术确实有些晦涩,很担心写完了达不到期望的效果,于是每每试图以简炼的文字表达,慢慢的就等到了今天。

    先说说我为什么专门对这项技术写一篇文章吧。记得当时在看STL/boost代码的时候经常遇到traits,当时惊叹于代码原来可以这样写,但是最初根本是看不懂的,查了一些资料才彻底理解了traits存在的意义。

    本质定义:加上一层间接性,换来以定的灵活性。

    看下面的代码:

    template <typename T> 
    struct is_void
    static const bool value = false; };

    template <> 
    struct is_void<void>
    static const bool value = true; };

     

    我们可以这样使用这份代码:

    Is_void<false>::value 调用第一份代码,也就是说只要我们传入一个参数像下面这样:

    Is_void<T>::value,其中T可以为任意类型,我们就可以判断这个类型是不是void在编译期。

    完整测试代码如下:

    template <typename T> 
    struct is_void

        static const bool value = false
    };

    template <> 
    struct is_void<void>

        static const bool value = true
    };

    int _tmain(int argc, _TCHAR* argv[])
    {
        std::cout<<is_void<int>::value;
        
        std::cout<<is_void<void>::value;
        return 0;
    }

     

    下面我们来看一个复杂点的例子,考验一下你的理解:

    namespace detail{
        template <bool b>
        struct copier
        {
           template<typename I1, typename I2>
           static I2 do_copy(I1 first, I1 last, I2 out);
        };

        template <bool b>
        template<typename I1, typename I2>
        I2 copier<b>::do_copy(I1 first, I1 last, I2 out)
        {
           while(first != last)
           {
              *out = *first;
              ++out;
              ++first;
           }
           return out;
        }
        template <>
        struct copier<true>
        {
           template<typename I1, typename I2>
           static I2* do_copy(I1* first, I1* last, I2* out)
           {
              memcpy(out, first, (last-first)*sizeof(I2));
              return out+(last-first);
           }
        };
        }

        template<typename I1, typename I2>
        inline I2 copy(I1 first, I1 last, I2 out)
        {
           typedef typename 
            boost::remove_cv<
             typename std::iterator_traits<I1>
              ::value_type>::type v1_t;
           typedef typename 
            boost::remove_cv<
             typename std::iterator_traits<I2>
              ::value_type>::type v2_t;
           enum{ can_opt = 
              boost::is_same<v1_t, v2_t>::value
              && boost::is_pointer<I1>::value
              && boost::is_pointer<I2>::value
              && boost::
              has_trivial_assign<v1_t>::value 
           };
           return detail::copier<can_opt>::
              do_copy(first, last, out);
    }

     

    总结

    本文试图以最简洁的方式阐述对C++ traits 的理解,当你理解了第二个例子的时候,相信你已经理解了C++ traits,恭喜你对C++ 的理解上了一个层次。

     

    Bibliography:

    http://www.boost.org/doc/libs/1_31_0/libs/type_traits/c++_type_traits.htm

     

  • 相关阅读:
    51nod 1117 聪明的木匠:哈夫曼树
    51nod 1010 只包含因子2 3 5的数
    51nod 2636 卡车加油
    51nod 2989 组合数
    51nod 2652 阶乘0的数量 V2
    51nod 1103 N的倍数
    51nod 2489 小b和灯泡
    51nod 1003 阶乘后面0的数量
    51nod 2122 分解质因数
    javascript中的setter和getter
  • 原文地址:https://www.cnblogs.com/pugang/p/2727378.html
Copyright © 2011-2022 走看看