STL中的Traits程式設計技巧

2021-08-01 06:00:09 字數 2817 閱讀 9394

《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 ...