模板的型別萃取

2021-08-05 18:38:24 字數 3943 閱讀 4380

功能
型別萃取,在stl中用到的比較多,用於判斷乙個變數是否為pod型別.

簡述來說可以用來判斷出某個變數是內建型別還是自定義型別.

通過型別萃取,萃取到變數型別,對不同變數進行不同處理,可以提公升程式效率(下面有具體講解).

應用場景
比如我們實現順序表,在對順序表進行擴容時,就靠重新開闢記憶體、拷貝物件.

拷貝物件時,就有兩種情況:一種是型別,比如int char…;還有一種是自定義型別,data類、string類.

對於內建型別,我們可以通過memset,來進行賦值.(擴充套件,淺拷貝相關的類也可以通過memset賦值)

而對於自定義型別,大多數深拷貝的物件來說,我們必須通過呼叫賦值語句來賦值.

因此,我們通常在拷貝物件時,為了不出現錯誤,都用賦值語句來賦值.

而我們如果有一種方法/機制可以判斷pod型別或者非pod型別.

對於pod型別用memset函式,對於非pod用賦值,這樣就能提高程式的效率

最大的功能
型別萃取的最大功能就是提高了程式的效率.例如下面的**,就會出現錯誤。

template

void copy( t* dst, t* src,size_t size)//這裡的size是資料個數

如果t型別是int,char,float ...這些內建型別,使用memcpy()函式拷貝沒有問題,並且使用memcpy()更快,比乙個乙個賦值賦值語句快很多,但是如果t型別是string這些自定義的型別(有自己的建構函式),使用memcpy()就是出現錯誤,string通過memcpy()拷貝後,程式就會蹦,因為mencpy()函式是淺拷貝,他只是把string例項化的這個物件的記憶體拷貝過去,_str淺拷貝過去,當出了這個作用域後,string呼叫自己的析構函式,因為一塊位址被兩個指標所指向,析構第二次時就會蹦。

那麼解決這個問題的辦法就是專門為string寫乙個拷貝函式,但是這樣沒有普遍性,寫乙個類專門寫乙個函式會很麻煩,模版的型別萃取就很好的解決了這個辦法,提高了運算效率,當物件是內建型別是使用mencpy(),當物件是自定義型別時,使用自己寫的函式。下面是實現模版的型別萃取的**。

型別萃取具體實現**
#pragma once

#include

#include

using

namespace

std;

// 預設是內建型別,char,int,double....

struct true_type

};//不是內建型別,比如自己定義的類,在專案中具體用到型別時,可以再自己定義

struct false_type

};template

struct type_extraction

; //這裡預設 is_pod_type 就是 false_type,因為在下面的偏特化中會

// typedef true_type is_pod_type.就會改變 is_pod_type

template

<>

struct type_extraction

;template

<>

struct type_extraction

;template

<>

struct type_extraction

;template

<>

struct type_extraction

;template

<>

struct type_extractionlong>

;template

<>

struct type_extraction

;template

<>

struct type_extractionchar>

;template

<>

struct type_extraction

;template

<>

struct type_extractionshort>

;template

<>

struct type_extractionint>

;template

<>

struct type_extraction

;template

<>

struct type_extractionlong>

;template

<>

struct type_extractionlong

long>

;template

<>

struct type_extractiondouble>

;template

struct type_extraction;

template

struct type_extraction

; //上面都是內建型別,因為原來預設 is_pod_type 是false_type ,

//所以上面的模版偏特化都把 is_pod_type 重新命名為 true_tpye

////使用引數(型別)推導到相應的函式模版

////內建型別,使用memcpy並不會導致錯誤。

template

void copy( t* dst, t* src,size_t size,true_type)//這裡的size是資料個數

//特殊型別,比如string,new時需要呼叫自己的建構函式時,需要自己實現拷貝,不能使用memcpy,會導致錯誤。

//第一種方法,根據引數型別自己選擇,因為引數有false_type,編譯器會自己挑選最匹配的

template

void copy( t* dst, t* src, size_t size, false_type)

}//第二種,根據萃取判斷型別中的 get_type()函式的返回值判斷是否是平凡型別(is_pod_type)

template

void copy( t* dst, t*src, size_t size)

else

}}#include

#include

#include"test.h"

using

namespace

std;

int main()

; string s2[10] = ;

copy(s1, s2, 5, type_extraction::is_pod_type());

cout

<< s1[1] << endl;

int a[10] = ;

int b[10] = ;

copy(a, b, 5);

cout

<< a[0] << endl;

return

0;}

模板 型別萃取

當我們在實現資料結構vector時,我們發現使用mencpy時只能實現基本型別的拷貝,而不能實現自定義型別的拷貝,比如說字串型別。這問題如何解決呢?在學習了模板和基於模板的型別萃取之後,我們就有方法是在實現基本型別的拷貝時使用memcpy,在遇到自定義型別時用for迴圈來拷貝。pragma once...

模板的型別萃取

鋪墊一下萃取的基礎點 pod 指c風格的struct結構體定義的資料結構,且struct結構體中只能含有常規的資料型別,不能函式自定義型別 函式過載 引數名相同,引數列表不同,返回型別可相同可不相同 模板的特化 模板引數在某個特定型別的具體實現,分為全特化和偏特化。類模板特化 template cl...

模板的型別萃取

初次接觸型別萃取是在運用模板實現seqlist的時候,拷貝構造和賦值運算子過載時,單純的使用memcopy 函式進行拷貝,只是單純的進行了淺拷貝,對於基本的資料型別是不會有任何錯誤的,但是如果是string型別時,單純的值拷貝顯然是不行的 超過了給定的buffer空間時 指向了同一塊開闢的空間,然後...