十分鐘讓你對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++ 的理解上了一個層次。
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章