1. 程式人生 > >C++之型別萃取技巧

C++之型別萃取技巧

在我們前面寫順序表的時候會產生一個問題。

使用型別萃取的原因

就是當你的順序表是自定義型別,我們進行順序表增容的時候,這個時候會出現一個問題,比如string型別,這個型別中有一個_buf與_ptr,當儲存少於16個的時候這時會儲存在_buf當中的,如果多於16個,那個會單獨開闢空間,進行儲存,這時拷貝的時候就是拷貝過去這個儲存的地址而已,所以這樣呼叫解構函式的時候,當增加容量的時候,這個時候會把儲存string的那塊空間進行釋放。會造成資料丟失的問題。

這裡寫圖片描述

所以,在這裡面我們提到一個型別萃取的技巧,可以把自定義型別和內建型別的區分開,然後對自定義型別的使用for迴圈拷貝,對於內建型別的,採用memcpy的方式進行拷貝。

示例:


#include<iostream>
#include<stdlib.h>

using namespace std;


//型別萃取
struct __truetype
{
    bool get()
    {
        return true;
    }
};

struct __falsetype
{
    bool get()
    {
        return false;
    }

};


template<typename T>

struct typetraits
{
    typedef __falsetype __ispodtype;

};

template
<> struct typetraits<int > { typedef __truetype __ispodtype; }; template<> struct typetraits<char > { typedef __truetype __ispodtype; }; template<> struct typetraits<short > { typedef __truetype __ispodtype; }; template<> struct typetraits<bool
> { typedef __truetype __ispodtype; }; template<> struct typetraits<unsigned int > { typedef __truetype __ispodtype; }; template<> struct typetraits<unsigned short > { typedef __truetype __ispodtype; }; template<> struct typetraits<unsigned long > { typedef __truetype __ispodtype; }; template<> struct typetraits<long > { typedef __truetype __ispodtype; }; template<> struct typetraits<long long > { typedef __truetype __ispodtype; }; template<> struct typetraits<unsigned long long > { typedef __truetype __ispodtype; }; template<> struct typetraits<long double > { typedef __truetype __ispodtype; }; template<> struct typetraits<double > { typedef __truetype __ispodtype; }; template<> struct typetraits<float > { typedef __truetype __ispodtype; }; template<typename T> void Copy(const T*src, T* dst, size_t size) { if (typetraits<T>::__ispodtype().get()) { cout << "__truetype:" << typeid(T).name() << endl; memcpy(dst, src, size*sizeof(T)); } else { cout << "__falsetype:" << typeid(T).name() << endl; for (size_t i = 0; i < size; i++) { dst[i] = src[i]; } } } void test() { int a1[8] = { 1, 2, 3, 4, 5, 6 }; int a2[8] = { 9, 5, 6, 7, 8, 2, 2 }; Copy(a1, a2, 3); cout << a2<<endl; string c1[10] = {"123","7989465","456321","4561","4563"}; string c2[5] = {"654","312","a"}; Copy(c1, c2, 3); } int main() { test(); system("pause"); return 0; }

在這裡我們採用了模板的特化,這裡使用了全特化,直接給int,double等內建型別做特化。

在這裡我們設定內建型別是truetype,設定自定義型別是falsetype,然後我們通過不同的型別利用get()函式返回不同的布林值,這樣對內建型別採用memcp拷貝,對於非內建型別,採用for迴圈拷貝,這樣就能實現我們想要的結果了。