初次接触类型萃取是在运用模板实现seqlist的时候,拷贝构造和赋值运算符重载时,单纯的使用memcopy(),函数进行拷贝,只是单纯的进行了浅拷贝,对于基本的数据类型是不会有任何错误的,但是如果是string类型时,单纯的值拷贝显然是不行的(超过了给定的buffer空间时),指向了同一块开辟的空间,然后析构时会出现问题。所以一开始直接调用赋值运算符的重载,这样显然不会出现问题,但是对基本的数据类型而言,这样调用的效率显然是没有直接使用memcopy()高效的。
所以类型萃取的出现就是很有必要的,将无关痛痒的类型直接使用memcopy()进行拷贝,其余的使用赋值运算符的重载来进行实现。
类型萃取是在模板的基础上区分内置类型和其他类型,原理是将内置类型全部特化,然后再进行区分。
//类型萃取
#include<iostream>
using namespace std;
struct __TrueType
{
bool Get()
{
return true;
}
};
struct __FalseType
{
bool Get()
{
return false;
}
};
template <class _Tp>
struct TypeTraits
{
typedef __FalseType __IsPODType; //不是内置类型则为 __FALSETYPE
};
//内置类型全部特化
template <>
struct TypeTraits< bool>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< char>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned char >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< short>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned short >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< int>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned int >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned long >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long long >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned long long>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< float>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< double>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long double >
{
typedef __TrueType __IsPODType;
};
template <class _Tp>
struct TypeTraits< _Tp*>
{
typedef __TrueType __IsPODType;
};
//
// 使⽤参数推导的萃取处理
//
//template <class T>
//void Copy(const T* src, T* dst, size_t size, __FalseType)
//{
// cout << "__FalseType:" << typeid(T).name() << endl;
// for (size_t i = 0; i < size; ++i)
// {
// dst[i] = src[i];
// }
//}
//template <class T>
//void Copy(const T* src, T* dst, size_t size, __TrueType)
//{
// cout << "__TrueType:" << typeid(T).name() << endl;
// memcpy(dst, src, size*sizeof (T));
//}
//void Test1()
//{
// string s1[10] = { "1", "2", "3", "4444444444444444444444444" };
// string s2[10] = { "11", "22", "33" };
// Copy(s1, s2, 10, TypeTraits <string>::__IsPODType());
// Copy(s1, s2, 10);
//
// int a1[10] = { 1, 2, 3 };
// int a2[10] = { 0 };
// Copy(a1, a2, 10, TypeTraits <int>::__IsPODType());
// Copy(a1, a2, 10);
//}
//使用参数来 推导类型萃取
template<typename T>
void Copy(const T* src, T* dst, size_t size)
{
if (TypeTraits <T>::__IsPODType().Get() == 0) //不是内置类型
{
cout << "赋值运算符重载" << endl;
for (size_t i = 0; i < size; ++i)
{
dst[i] = src[i];
}
}
else
{
cout << "使用memcpy()" << endl;
memcpy(dst, src, size*sizeof(T));
}
}
void Test1()
{
string s1[10] = { "1", "2", "3", "4444444444444444444444444" };
string s2[10] = { "11", "22", "33" };
Copy(s1, s2, 10);
Copy(s1, s2, 10);
int a1[10] = { 1, 2, 3 };
int a2[10] = { 0 };
Copy(a1, a2, 10);
Copy(a1, a2, 10);
}
int main()
{
Test1();
system("pause");
return 0;
}