c++模板之萃取

xiaoxiao2021-02-27  330

假如,我们要设计一个_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; }; //特化TypeTraits进行类型判断(由于内置类型已经确定,而自定义类型不确定,因此经常特化内置类型) 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]; //相当与调用string的赋值运算符重载 } 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() { //test1(); test2(); system("pause"); return 0; }

简单调用关系图如下:

转载请注明原文地址: https://www.6miu.com/read-2475.html

最新回复(0)