功能型別萃取,在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空間時 指向了同一塊開闢的空間,然後...