模板(泛型)實際上就是巨集定義乙個型別,此型別是乙個通用型別(故又叫泛型),把具體型別(包括指標型別)帶入進去就會形成乙個新的型別。下面是代入時兩種編譯錯誤的解決方法:
一、模板(泛型)具型成 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查詢。讓我們看以...