traits的應用場合

2021-06-05 15:11:57 字數 2989 閱讀 9262

模板(泛型)實際上就是巨集定義乙個型別,此型別是乙個通用型別(故又叫泛型),把具體型別(包括指標型別)帶入進去就會形成乙個新的型別。下面是代入時兩種編譯錯誤的解決方法:

一、模板(泛型)具型成 int::valuetype 時(代入基本型別),這顯然編譯不過,就像下面這樣偏特化處理

// my_type_traits.h開始

#ifndef my_type_traits_h

#define my_type_traits_h

struct my_true_type ;

struct my_false_type ;

template struct my_type_traits;

template<> struct my_type_traits;

#endif

// my_type_traits.h結束

// my_destruct.h開始

#ifndef my_destruct_h

#define my_destruct_h

#include #include "my_type_traits.h"

using std::cout;

using std::endl;

template inline void myconstruct(t1 *p, const t2& value)

template inline void mydestroy(t *p)

template inline void _mydestroy(t *p, my_true_type)

template inline void _mydestroy(t *p, my_false_type)

#endif

// my_destruct.h結束

// test_type_traits.cpp開始

#include #include "my_destruct.h"

using std::cout;

using std::endl;

class testclass

testclass(const testclass& test_class)

~testclass()

private:

int *data;};

int main(void)

}// test_type_traits.cpp結束

二、模板(泛型)具型成 int*::valuetype 時(代入各種型別指標),這顯然編譯不過,就像下面這樣偏特化處理

traits技術可以用來獲得乙個 型別 的相關資訊的。 首先假如有以下乙個泛型的迭代器類,其中型別引數 t 為迭代器所指向的型別:

template

<

typename

t>

class

myiterator

;當我們使用myiterator時,怎樣才能獲知它所指向的元素的型別呢?我們可以為這個類加入乙個內嵌型別,像這樣:

template

<

typename

t>

class

myiterator

;這樣當我們使用myiterator型別時,可以通過 myiterator::value_type來獲得相應的myiterator所指向的型別。

現在我們來設計乙個演算法,使用這個資訊。

template 

typename

myiterator::value_type foo(myiteratori)

這裡我們定義了乙個函式foo,它的返回為為  引數i 所指向的型別,也就是t,那麼我們為什麼還要興師動眾的使用那個value_type呢? 那是因為,當我們希望修改foo函式,使它能夠適應所有型別的迭代器時,我們可以這樣寫:

template 

//這裡的i可以是任意型別的迭代器

typename

i::value_type foo(i i)

現在,任意定義了 value_type內嵌型別的迭代器都可以做為foo的引數了,並且foo的返回值的型別將與相應迭代器所指的元素的型別一致。至此一切問題似乎都已解決,我們並沒有使用任何特殊的技術。然而當考慮到以下情況時,新的問題便顯現出來了:

原生指標也完全可以做為迭代器來使用,然而我們顯然沒有辦法為原生指標新增乙個value_type的內嵌型別,如此一來我們的foo()函式就不能適用原生指標了,這不能不說是一大缺憾。那麼有什麼辦法可以解決這個問題呢? 此時便是我們的主角:型別資訊榨取機 traits 登場的時候了

....drum roll......

我們可以不直接使用myiterator的value_type,而是通過另乙個類來把這個資訊提取出來:

template

<

typename

t>

class traits

;這樣,我們可以通過 traits::value_type 來獲得myiterator的value_type,於是我們把foo函式改寫成:

template 

//這裡的i可以是任意型別的迭代器

typename

traits::value_type foo(i i)

然而,即使這樣,那個原生指標的問題仍然沒有解決,因為trait類一樣沒辦法獲得原生指標的相關資訊。於是我們祭出c++的又一件利器--偏特化(partial specialization):

template

<

typename

t>

class traits

//注意 這裡針對原生指標進行了偏特化

;通過上面這個 traits的偏特化版本,我們陳述了這樣乙個事實:乙個 t* 型別的指標所指向的元素的型別為 t。

如此一來,我們的 foo函式就完全可以適用於原生指標了。比如:

int* p;

....

inti = foo(p);

traits會自動推導出 p 所指元素的型別為 int,從而foo正確返回。

extern C 的應用場合

首先extern c 是一句申明語句,它的意思是告訴編譯器用c的規則去編譯該申明語句後的內容,一般都是申明函式。我們都知道c 具有函式過載的功能,比如說某個檔案包含下面這兩個函式 int foo int a int foo double a 它們的函式名都長得一樣,但是引數型別不一樣。如果該檔案是....

I O復用的應用場合

i o復用 select poll 典型使用在下列網路應用場合 1 當客戶處理多個描述字 通常是互動式輸入和網路套介面 時,必須使用i o復用。2 乙個客戶同時處理多個套介面是可能的,不過比較少見。3 如果乙個tcp伺服器既要處理監聽套介面,又要處理已連線的套介面,一般就要使用i o復用。4 如果乙...

oracle跳躍索引的應用場合

索引跳躍式掃瞄 index skip scan 是oracle9i的乙個新的執行特性,尤其適用於使用連線索引和訪問多值索引的oracle查詢。根據 索引跳躍式掃瞄 index skip scan 是oracle9i的乙個新的執行特性,尤其適用於使用連線索引和訪問多值索引的oracle查詢。讓我們看以...