在前面用模板写顺序表时,我们遇到了一个问题,如果用memcpy拷贝元素效率会比较高,但是memcpy实际上是浅拷贝,对于string类型则会出现问题,这时就要用for循环来拷贝元素了
因此,我们想到了对于内置类型(比如:int,double,char等类型),我们用memcpy实现拷贝元素,而对于String这样的自定义类型,我们使用for循环拷贝。这样,我们需要将内置类型和自定义类型进行区分。
第一种,我们可以定义一个函数,将自定义类型名称当成字符串,与函数的参数比较,内置类型返回为true,自定义类型返回为false
bool IsPOD(const char* TypeName)
{
static char* p[] = { "int", "double", "char" };
for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++)
{
if (strcmp(p[i], TypeName) == 0)
return true;
}
return false;
}
template <class T>
void Copy(T* dst, T* src, size_t size)
{
if (IsPOD("int"))
memcpy(dst, src, size*sizeof(T));
else
{
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
}
}
第二种,我们使用类模板及其特化
struct TrueType//内置类型设置为true
{
static bool IsPODType()
{
return true;
}
};
struct FalseType//自定义类型设置为false
{
static bool IsPODType()
{
return false;
}
};
template<class T>//模板类
struct TypeTraits//自定义类型为一般的,内置类型为特化的
{
typedef FalseType PODType;
};
template<>
struct TypeTraits<int>//特化int
{
typedef TrueType PODType;
};
template<>
struct TypeTraits<double>//特化double
{
typedef TrueType PODType;
};
template<>
struct TypeTraits<char>//特化char
{
typedef TrueType PODType;
};
template<>
struct TypeTraits<float>//特化float
{
typedef TrueType PODType;
};
template <class T>
void Copy(T* dst, T* src, size_t size)
{
if (TypeTraits<T>::PODType::IsPODType())
memcpy(dst, src, size*sizeof(T));
else
{
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
}
}
void FunTest()
{
int arr1[5] = { 1, 2, 3, 4, 5 };
int arr2[5];
Copy<int>(arr2, arr1, sizeof(arr1) / sizeof(arr1[0]));
for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
cout << arr2[i] << " ";
cout << endl;
string arr3[3] = { "aaa", "bbb", "ccc" };
string arr4[3];
Copy<string>(arr4, arr3, sizeof(arr3) / sizeof(arr3[0]));
for (int i = 0; i < sizeof(arr3) / sizeof(arr3[0]); i++)
cout << arr4[i] << " ";
cout << endl;
}
也可以这样:
struct TrueType
{};
struct FalseType
{};
template<class T>
struct TypeTraits//自定义类型
{
typedef FalseType PODType;
};
template<>
struct TypeTraits<int>
{
typedef TrueType PODType;
};
template<class T>
void _Copy(T* dst, T* src, size_t size, TrueType)
{
memcpy(dst, src, sizeof(T)*size);
}
template<class T>
void _Copy(T* dst, T* src, size_t size, FalseType)
{
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
}
template <class T>
void Copy(T* dst, T* src, size_t size)
{
_Copy(dst, src, size, TypeTraits<T>::PODType());
}
测试结果: