十分钟让你对C++ Traits大彻大悟

长平狐 发布于 2013/01/11 10:32
阅读 437
收藏 1

转自:http://www.cnblogs.com/pugang/archive/2012/10/17/2727378.html


最近和一个朋友闲聊的时候他对我说一个人对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




原文链接:http://blog.csdn.net/fjb2080/article/details/8084507
加载中
返回顶部
顶部