traits技術(shù)被廣泛應(yīng)用于STL中,通過(guò)它您可以輕松的萃取出一個(gè)對(duì)象的特性。在STL中也是通過(guò)它來(lái)實(shí)現(xiàn)性能的最優(yōu)化,比如一個(gè)對(duì)象是個(gè)POD對(duì)象(Plain Old Data),則在拷貝過(guò)程中直接可以通過(guò)memcpy等函數(shù)拷貝,而無(wú)需調(diào)用拷貝構(gòu)造函數(shù)或operator=。
先來(lái)看看STL中最基本的對(duì)象iterator
template <typename T, typename Size = size_t, typename Difference = ptrdiff_t>
struct iterator
{
typedef T value_type;
typedef Difference difference_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef iterator<T, Size, Difference> self;
};
template <typename T, typename Size = size_t, typename Difference = ptrdiff_t>
struct const_iterator : public iterator<T>
{
};
由以上代碼可知,對(duì)于每一個(gè)iterator必須定義其value_type,size_type,difference_type,pointer,reference,const_pointer,const_reference和self類型。
一、value_type
value_type指示了該迭代器所保存的值類型
二、difference_type
difference_type用來(lái)指示兩個(gè)迭代器之間的距離類型
三、pointer,reference,const_pointer,const_reference
分別是所指之物的指針,引用,指針常量和引用常量的類型
四、self
self為該迭代器自身的類型
下面來(lái)看一下iterator_traits,iterator_traits主要用來(lái)萃取迭代器iterator的值類型等
template <typename Iterator>
struct iterator_traits
{
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
typedef typename Iterator::const_pointer const_pointer;
typedef typename Iterator::const_reference const_reference;
typedef typename Iterator::self self_type;
};
這里有一點(diǎn)可以提前預(yù)告一下,vector作為一個(gè)容器,其內(nèi)部是使用指針作為迭代器的,那么我們?nèi)绾屋腿〕鏊闹殿愋偷饶兀?br />
答案很簡(jiǎn)單,特例化,那么我們就來(lái)為iterator_traits分別做兩種T*和const T*的特例化
template <typename T>
struct iterator_traits<T*>
{
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef T* self_type;
};
template <typename T>
struct iterator_traits<const T*>
{
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef const T* self_type;
};
至此,我們可以用iterator_traits萃取出每種iterator的值類型等內(nèi)容了。
之前已經(jīng)說(shuō)到了,通過(guò)traits可以萃取出一些對(duì)象的特性,從而提高代碼的效率。事實(shí)確實(shí)如此,通過(guò)traits可萃取出一個(gè)對(duì)象是否是一個(gè)POD對(duì)象,對(duì)于一個(gè)POD對(duì)象,我們?cè)诳截悤r(shí),不應(yīng)該使用其拷貝構(gòu)造函數(shù)或是operator=,而用memcpy則效率更高。
下面我們來(lái)看一下__type_traits
struct __true_type
{
};
struct __false_type
{
};
template <typename I>
struct __type_traits
{
typedef __false_type has_default_construct;
typedef __false_type has_copy_construct;
typedef __false_type has_assign_operator;
typedef __false_type has_destruct;
typedef __false_type is_POD;
};
不得不提的是其中分別用__true_type和__false_type來(lái)表示是否存在這個(gè)特性。
那么我們?nèi)绾屋腿〕龌A(chǔ)類型諸如int,char等的特性呢?
答案依然是特例化,這里代碼不再貼出,文末會(huì)給出完整代碼的詳細(xì)地址。
最后我們使用一個(gè)hash_destruct的函數(shù)來(lái)獲取出這個(gè)類型是否有析構(gòu)函數(shù)。
template <typename T>
inline auto has_destruct(const T&)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
{
return static_cast<typename __type_traits<T>::has_destruct*>(0);
}
template <typename T>
inline auto has_destruct(T*)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
{
static_assert(false, "Please use const T& not T*");
return static_cast<typename __type_traits<T>::has_destruct*>(0);
}
template <typename T>
inline auto has_destruct(const T*)->decltype(static_cast<__type_traits<T>::has_destruct*>(0))
{
static_assert(false, "Please use const T& not const T*");
return static_cast<typename __type_traits<T>::has_destruct*>(0);
}
不得不提的是C++0x的確很強(qiáng)大,可以通過(guò)形參來(lái)確定返回值的類型,這樣我們就可以萃取出這個(gè)類型的has_destruct域是__true_type或是__false_type了。
最后來(lái)看看construct和destruct的代碼,在STL中對(duì)象的內(nèi)存分配和構(gòu)造是被分開的,對(duì)于基礎(chǔ)對(duì)象int,char等,在析構(gòu)時(shí)我們無(wú)需調(diào)用其析構(gòu)函數(shù)。
下面來(lái)看construct和destruct的實(shí)現(xiàn)
template <typename T1, typename T2>
inline void construct(T1* p, const T2& value)
{
new (p) T1(value);
}
template <typename T>
inline void destruct(T* p, __true_type*)
{
p->~T();
}
template <typename T>
inline void destruct(T*, __false_type*)
{
}
template <typename ForwardIterator>
inline void destruct(ForwardIterator first, ForwardIterator last)
{
while(first != last)
{
destruct(first, has_destruct(*first));
++first;
}
}
至此,關(guān)于traits技術(shù)和construct及destruct的講解已完成,完整的代碼請(qǐng)到
http://qlanguage.codeplex.com/下載
posted on 2012-06-02 22:39
lwch 閱讀(2587)
評(píng)論(3) 編輯 收藏 引用 所屬分類:
STL