十分鍾讓你對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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM