《stl原始碼剖析》一書中提到traits程式設計技法,它的作用是獲取型別(associated type)的特性。這樣講比較抽象,到底什麼是相應型別,或者到底什麼時候需要用到traits程式設計技法呢?先來看乙個例子。
假設有這麼乙個函式,接受乙個iterator,返回這個iterator所指代的型別,其實這個函式就是實現了typeof(),但是c++裡面並沒有typeof()操作符。
vector
iv = ;
vector
::iterator it1 = iv.begin(), it2 = iv.end();
template
// ret-type
fun(iterator it)
那麼函式的返回型別的該怎麼寫呢?再往下看,如果這個iterator由我們自己來實現(事實上stl的iterator的實現和這個十分類似)
template
struct myiter // 為了方便訪問成員,用struct
t& operator*() const
//...
};template
typename i::value_type // 函式返回型別
func(i ite)
typename
,編譯器並不知道myiter::value_type
代表的是乙個型別或是乙個member function
或是乙個typename
的用意在於告訴編譯器這是乙個型別,如此才能順利通過。這樣我們就可以通過func函式獲取迭代器所指代的型別了。
但是這樣還是有乙個問題,並不是所有迭代器都是class type的。比如原生的指標就不是,這樣就沒有辦法為它定義內嵌型別了。現在就輪到traits程式設計技法發揮作用的時候了:
template
struct iterator_traits
// func可以這麼寫
template
typename iterator_traits::value_type
func
(i ite)
現在我們可以利用模板的template partial specialization(偏特化)定義乙個偏特化版的iterator_traits專門用於萃取原生指標的型別。
template
struct iterator_traits
同理,對於指向常量的指標,我們也可以專門偏特化乙個版本來萃取它的型別。
template
struct iterator_traits
這裡再提一點題外話,《stl原始碼剖析》提到,stl只對迭代器加以規範,制定出iterator_traits這樣的東西,sgi則把這種技法擴大到了迭代器以外,定義了__type_traits。雙底線字首值這是sgi stl內部特有的,不在stl的標準規劃之中。
如果說iterator_traits負責萃取迭代器的特性,那麼__type_traits則負責萃取型別的特性。這裡所關注的型別特性有一下5個:
has_trivial_default_constructor
has_trivial_copy_constructor
has_trivial_assignment_operator
has_trivial_destructor
is_pod_type
有了這些型別特性,我們在對這個型別進行構造、析構、拷貝、賦值等操作時,就可宜採用最有效率的措施。比如對於has_trivial_copy_constructor,那麼我只直接通過記憶體拷貝來實現物件拷貝以提高效率。
參照iterator_traits的經驗,我們希望通過下面這樣的方法來獲取使用__type_traits
__type_traits:
:has_trivial_default_constructor
__type_traits:
:has_trivial_copy_constructor
__type_traits:
:has_trivial_assignment_operator
__type_traits:
:has_trivial_destructor
__type_traits:
:is_pod_type
我們希望上式能夠返回給我們乙個物件的型別,而不是單純的bool型別,這樣編譯器可以通過這個物件的型別來進行引數推導。為此,上述式子應該傳回
struct __true_type{};struct __false_type
{};
這是兩個空白classes,沒有任何成員,我們知道編譯器在進行引數推導的時候,並不會真的去生成乙個物件,因此,這麼做是不會帶來額外負擔的,卻又能夠標示真假。
下面就是sgi的__type_traits
實現:
template struct __type_traits// 下面是對c++標量型定義的__type_traits的特化版的乙個舉例。
// __stl_template_null 定義為 template<>
__stl_template_null struct __type_traits
如果自己實現乙個類,需要告訴stl這個類的特性,那麼為這個類也特化乙個模板就可以了。
STL中,traits程式設計技法 模板
stl中,traits程式設計技法得到了很大的應用,了解這個,才能一窺stl奧妙所在。先將自己所理解的記錄如下 traits技術可以用來獲得乙個 型別 的相關資訊的。首先假如有以下乙個泛型的迭代器類,其中型別引數 t 為迭代器所指向的型別 template class myiterator 當我們使...
STL之traits程式設計技法
traits程式設計技法利用了 內嵌型別 的程式設計技巧與編譯器的template引數推導功能。下面主要看看利用traits程式設計技法實現的迭代器萃取機制。5種迭代器型別定義 struct input iterator tag struct output iterator tag struct f...
STL之迭代器與traits程式設計技法
iterator模式定義如下 提供一種方法,使之能夠依序巡防某個聚合物所含的各個元素,而又不暴露該聚合物的內部表示式。迭代器是一種smart pointer 舉例auto ptr template class auto ptr auto ptr template auto ptr auto ptr ...