假如,我们要设计一个_Copy的模板函数。我们为了提高效率采用memcpy,可以这样写:
template<typename T>
T* _Copy(T* dest, T* src, size_t n)
{
memcpy(dest, src, sizeof(T)*n);
return dest;
}
我们知道一般的类型(比如int,float,double,char等)进行复制的时候采用memcpy效率会高一些;而像string或者是其他的一些自定义类型(并且成员有指针类型的话),继续用mencpy将出现错误,采用for循环进行一个一个复制(赋值运算符重载)才是正确的方法。
自定义类型for循环代码:
template<typename T>
T* _Copy(T* dest, T* src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
dest[i] = src[i]; //相当与调用string的赋值运算符重载
}
return dest;
}
但是采用for循环拷贝效率明显不如memcpy函数高,如何才能让程序在运行内置类型时调用memcpy,而拷贝自定义类型时防止错误调用for循环拷贝,两者兼顾呢??
为了进行不同的类型调用不同的方式进行拷贝,我们可以利用模板及模板的特化,在特化中返回它的类型进而进行判断要进行那种方式的拷贝。为了统一,也可在模板即特化中重命名它的类型,当所给的类型与所有特化有匹配时,执行一种方式进行拷贝;当所给的类型与所有特化没有匹配时,执行另一种方式进行拷贝。
以下是源代码:
#include <iostream>
using namespace std;
#include <string>
struct _TureType
{
bool get()
{
return true;
}
};
struct _FalseType
{
bool get()
{
return false;
}
};
template<typename T>
struct TypeTraits
{
typedef _FalseType _IsPodType;
};
template<>
struct TypeTraits<int>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<unsigned int>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<double>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<float>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<char>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<unsigned char>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<short>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<long>
{
typedef _TureType _IsPodType;
};
template<>
struct TypeTraits<long long>
{
typedef _TureType _IsPodType;
};
template<typename T>
T* _Copy(T* dest, T* src, size_t n, _TureType)
{
memcpy(dest, src, sizeof(T)*n);
return dest;
}
template<typename T>
T* _Copy(T* dest, T* src, size_t n, _FalseType)
{
for (size_t i = 0; i < n; i++)
{
dest[i] = src[i];
}
return dest;
}
template<typename T>
T* _Copy(T*dest, T* src, size_t n)
{
return _Copy(dest, src, n, TypeTraits<T>::_IsPodType());
}
void test1()
{
int a[10] = { 2, 2, 3, 4, 5, 6, 7, 8, 8 };
int b[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
_Copy(a, b, 5);
}
void test2()
{
string a[5] = { "abc", "def", "ghi", "123", "456" };
string b[4] = {"111111111111111111111111111111111111111", "222222", "333333", "44444444"};
_Copy(a, b, 3);
}
int main()
{
test2();
system("pause");
return 0;
}
简单调用关系图如下: