c 學習 「型別萃取」

2021-09-08 21:46:40 字數 2819 閱讀 5838

c++型別萃取一般用於模板中,當我們定義乙個模板函式後,需要知道模板型別形參並加以運用時就可以用型別萃取。

比如我們需要在函式中進行拷貝,通常我們可以用內建函式memcpy或者自己寫乙個for迴圈來進行拷貝。

template

void

copy

(t*src, t*des,

int size)

//for + 迴圈

}}

這是乙個通用的拷貝函式,可以拷貝多種型別的資料,比如內建型別的int、double等和自定義結構體或類型別。我們可以看到其中用了兩種拷貝方式—memcpy和for迴圈。

我們知道memcpy進行拷貝時效率很高,但是它是將所拷貝物件中的值全部原樣地複製到目標物件中去,那麼如果我們在對帶指標的自定義物件進行拷貝時就會把源物件指標值拷貝到目標物件內指標內去,這樣就造成了多個物件的指標指向同一塊記憶體,這樣就成了淺拷貝了。這裡為了避免淺拷貝的發生就特意用效率相對較低的for迴圈來對自定義型別的物件進行拷貝工作。因此這個拷貝函式裡面就給出了兩種拷貝方式。

型別萃取—解析:

struct true_type

}struct false_type

}

template 

struct typetrait

;template <

>

struct typetrait<

int>

;

解析

這裡給出了四個結構體(結構體預設訪問型別為public比預設型別為private的類方便)

·前兩個結構體乙個為_truetype表示內建型別,乙個為_falsetype表示自定義型別,兩個結構體內都定義了乙個返回型別為bool型別的函式get(),其中乙個返回true乙個返回false。

·第三個為結構體模板,模板內將結構體型別_falsetype重定義為_ispodtype(ps:在類或者結構體內對型別重定義後,重定義的型別屬於這個類或結構體的成員型別,其作用域在這個類或結構體裡面),當我們用這個結構體內的_ispodtype型別定義乙個物件來呼叫函式get()時就會返回乙個false,表示t型別為自定義型別。

·第四個結構體是對第三個結構體模板的特化,這裡特化成為int型別,當然也可以特化為double或者char型別,這個結構體裡面將結構體型別_truetype重定義為_ispodtype,當傳入的引數為int型別時用_ispodtype定義物件就可以呼叫_truetype結構體內的get函式,返回乙個true,表示傳入了內建型別。

進行測試: 對這段**作了解釋後,來結合上面的copy函式執行一下,看能不能對內建型別和自定義型別的引數執行不同的拷貝方式。我們先呼叫copy函式拷貝內建型別:

int

main()

;const size_t size =

sizeof

(array1)

/sizeof

(array1[0]

);int array2[size]=;

copy

(array2, array1, size)

;for

(size_t i =

0; i < size; i++

) cout << endl;

return0;

}

執行結果:

那麼現在來對自定義型別的物件進行拷貝:

int

main()

;const size_t size =

sizeof

(s1)

/sizeof

(s1[0]

);string s2[size]=;

copy

(s2, s1, size)

;for

(size_t i =

0; i < size; i++

)return0;

}

測試結果:

我們可以看到這次copy是按照for迴圈進行拷貝的。

因為所有的指標都用4個位元組儲存,且不會造成淺拷貝的問題,其實際上屬於內建型別。

給出其他內建型別的特化:

struct _typetraits<

short

>

;struct _typetraits<

long

>

;struct _typetraits<

long

long

>

;struct _typetraits<

unsigned

>

;template<

>

struct _typetraits<

char

>

;struct _typetraits<

unsigned

char

>

;template<

>

struct _typetraits<

double

>

;struct _typetraits<

float

>

;struct _typetraits

;

C 型別萃取

在c 中我們可以通過typeid來獲取乙個型別的名稱 內建型別和自定義型別都可以 但是我們不能用這種方式獲取來的名稱做變數的宣告。那麼在c 中怎樣識別物件的型別呢?我們可以通過型別萃取的方式來區分內建型別和自定義型別。例如 我們在seqlist中要用到型別萃取,因為內建型別我們可以通過memcopy...

C 型別萃取

當我們遇到這樣的場景時,我們會用到型別萃取 template void copy t dst,t str,size t n 模板函式copy void test string s2 10 int l1 10 int l2 10 copy s1,s2,10 copy l1,l2,10 for size...

C 型別萃取

型別萃取依靠的就是模版的特化,模版的特化又分為全特化和偏特化,根據不同的情況做相應的呼叫。函式模版特化 函式模版只有全特化,而沒有偏特化。沒有偏特化的原因是已經有了函式過載。通用模版並不總是正確的,在某些情況下有可能是錯誤的。例如 include using namespace std templa...