C++类型萃取

来源:互联网 发布:邮箱数据购买 编辑:程序博客网 时间:2024/04/30 02:01

在Seqlist中,我们对于内置类型,通过memcopy和memmove这两个方式进行拷贝,自定义类型或string类型我们要通过for循环赋值的方式拷贝。

那么系统如何区分是哪种类型呢?

虽然通过typeid可以获取变量类型,但是这样获取到的类型,无法用来做变量的声明。

因此,我们这里引入类型萃取

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"template<class T>void Copy(T* dst, T* src, size_t size){     memcpy(dst, src, sizeof(T)*size);}int main(){     string s1[10] = { "123", "456", "7" };     string s2[10] = { "abc", "def", "g" };     Copy<string>(s1, s2, 10);     return 0;}

这里写图片描述

这里写图片描述

从上面的Copy函数可以看出,拷贝的工作已经成功完成,但是在程序结束时崩溃了。
这是因为memcpy是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
对同一块内存析构多次,导致程序崩溃。

所以对于string类型的拷贝, 我们通过for循环来进行:

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"template<class T>void Copy(T* dst, T* src, size_t size){     //memcpy(dst, src, sizeof(T)*size);     for (int i = 0; i < size; ++i)     {          dst[i] = src[i];     }}int main(){     string s1[10] = { "123", "456", "7" };     string s2[10] = { "abc", "def", "g" };     Copy<string>(s1, s2, 10);     return 0;}

由上面的两种情况,我们可以看出,memcpy作为库函数,拥有很高的效率, 但是涉及到内存问题时,十分容易出错。
通过for循环的拷贝工作,不易出错,但是效率低。

两种拷贝方式各有各自的优势与劣势,对于不同的类型拷贝适合不同的拷贝方式,这里就用到了类型萃取。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"struct __TrueType{     static bool Get()     {          return true;     }};struct __FalseType{     static bool Get()     {          return false;     }};template <class _Tp>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;};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));}template <class T>void Copy(const T* src, T* dst, size_t size){     cout << "__TrueType:" << typeid(T).name() << endl;     if (TypeTraits <T>::__IsPODType().Get())     {          memcpy(dst, src, size*sizeof (T));     }     else     {          for (size_t i = 0; i < size; ++i)          {              dst[i] = src[i];          }     }}int main(){     string s1[10] = { "123", "456", "7" };     string s2[10] = { "abc", "def", "g" };     //Copy<string>(s1, s2, 10);     return 0;}
0 0