POD类型萃取
POD: plain old data 平凡类型(⽆关痛痒的类型)--基本类型
C++可以通过typeid获取到⼀个类型的名称,但是不能拿来做变量的声明。所以我们可以通过类型萃取对内置类型和非内置类型进行区分,其原理就是将内置类型全特化,这样我们在进行拷贝的时候就可以对内置类型和非内置类型进行不同的处理来提高效率。像sting这种深浅拷贝的问题也可以解决。
主要应用:SeqList,统⼀内存管理项⽬以及STL。
#pragma once
#include <string>
struct __TrueType
{
bool Get()
{
return true;
}
};
struct __FalseType
{
bool Get()
{
return false;
}
};
template<class T>
struct TypeTraits
{
//默认为非内置类型
typedef __FalseType __IsPodType;
};
//模板的全特化,特化内置类型
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;
};
//ptr也是内置类型,原生指针没有析构函数
template<class T>
struct TypeTraits<T*>
{
typedef __TrueType __IsPodType;
};
// 使⽤参数推导的萃取处理
template<class T>
void Copy(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(T* src, T* dst, size_t size, __TrueType)
{
cout << "__TrueType" << typeid(T).name() << endl;
memcpy(dst, src, size*sizeof(T));
}
// 使⽤萃取判断类型的Get函数判断是否是POD类型来处理
template<class T>
void Copy(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 TestTypeTraits()
{
string s1[10] = { "1a", "2b", "abc", "absxhdessssdddd" };
string s2[10] = { "1", "2", "3", "5" };
Copy(s1, s2, 10, TypeTraits<string>::__IsPodType());
Copy(s1, s2, 10);
for (size_t i = 0; i < 10; i++)
{
cout << s2[i] << " ";
}
cout << endl;
int a1[10] = { 1, 2, 3, 4, 4 };
int a2[10] = { 4, 6, 7, 8, 5, 4 };
Copy(a1, a2, 10, TypeTraits<int>::__IsPodType());
Copy(a1, a2, 10);
}