假如,我们要设计一个_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;
}
简单调用关系图如下: