C++类型萃取
来源:互联网 发布:pre绘图软件 编辑:程序博客网 时间:2024/05/29 14:42
在利用模板来实现容器vector的时候,由于是泛型编程,所以参数类型是可以说是任意的,而当我们希望实现对一块连续空间进行拷贝的时候,有两种实现方式,一种是memcpy函数实现,另一种则是通过for循环一个一个赋值。 memcpy是一种很高效的方式,但是,当拷贝自定义类型时就会牵扯到深浅拷贝的问题,因为memcpy的实现方式是浅拷贝,在释放内存的时候往往会因为多次释放同一块内存而导致程序崩溃。 所以当拷贝自定义类型时就需要采用for循环一个一个赋值(赋值运算符重载的时候的实现方式是深拷贝)的方式来实现拷贝了。可能有人会有疑问,为什么不直接选择将所有的拷贝方式都用for循环来实现呢。因为for循环的效率很低。而memcpy的效率高,而且当T为内置类型时,memcpy不仅不会出错而且效率还很高。 自然而然地,就想到利用一个方法能够实现在拷贝内置类型的时候使用memcpy,拷贝自定义类型的时候使用for循环。这样就既保证了程序既不会出错又高效。接下来就来实现这种方法-------**类型萃取**。
看代码:
struct TrueType{ bool Get() { return true; }};struct FalseType{ bool Get() { return false; }};
首先定义了TrueType和FalseType两个类,注意这两个类都是用struct关键字声明的,这是为了让类里边的成员默认为公有的,用class关键字来声明也可以,只要在类成员里边加将其声明为公有的就行了。
template<typename Ty>struct TypeTraits{ typedef FalseType IsPODType;};
这段代码声明了一个类模板,在类模板里边就只做一件事情,将FalseType重命名为 IsPODType 。在这个模板类中将所有的类型假定都为自定义类型。说明: IsPODType 是在类TypeTraits里边声明的,也就相当于类 TypeTraits 的一个成员类型,之后使用它的时候需要加 TypeTraits::作用域,记住,IsPODType 不是一个成员变量,只是一个成员类型,在后边的第一个测试函数会加以验证。
接下来要做的事情就是对内置类型进行特化。
template<>struct TypeTraits<int>{ typedef TrueType IsPODType;};template<>struct TypeTraits<char>{ typedef TrueType IsPODType;};template<>struct TypeTraits<short>{ typedef TrueType IsPODType;};template<>struct TypeTraits<size_t>{ typedef TrueType IsPODType;};template<>struct TypeTraits<long>{ typedef TrueType IsPODType;};template<>struct TypeTraits<double>{ typedef TrueType IsPODType;};template<class Ty>struct TypeTraits<Ty*>{ typedef TrueType IsPODType;};
在这里给出部内置类型的特化,相信读者已经看懂如何去特化参数为内置类型的类了,就不一一实现了。
接下来就是拷贝函数了
template<typename T>void Copy(T* dest, const T* src, size_t size){ //获取参数的类型的名称 cout << "Typename is: " << typeid(T).name() << endl; if (TypeTraits<T>::IsPODType().Get())//是内置类型 { memcpy(dest, src, size*sizeof(T)); } else { for (size_t i = 0; i < size; i++) { dest[i] = src[i]; } }}
**注意:**typeid可以获取到一个类型的名称,但是不能拿来做变量的声明。
最后就是测试函数了
void FunTest1()//测试内置类型{ cout << sizeof(TypeTraits<int>) << endl; int arr[] = { 1, 2, 3, 4, 5, 6 }; int array[10] = { 0 }; size_t size = sizeof(arr) / sizeof(arr[0]); Copy(array, arr, size); for (size_t i = 0; i < size; i++) { cout << array[i] << " "; } cout << endl;}void FunTest2()//测试自定义类型{ string s1[10] = { "1235", "2abdc", "hdfiig", "asdfghjk" }; string s2[10] = { "11", "22", "33" }; Copy(s2, s1, 10);}int main(){ FunTest1(); FunTest2(); return 0;}
先将第二个测试函数的调用注释掉,看第一个测试函数的结果:
对类TypeTraits求大小发现其大小为1,这说明这个类里边什么都没有,即IsPODType是并不是其成员变量。
Copy函数对内置类型进行拷贝,意料中的结果。调试看看Copy函数对自定义类型的拷贝是不是也是预料中的结果呢?
调试发现,对自定义类型的拷贝也很成功。
对类型萃取的讲解就到这里,欢迎读者提出宝贵意见哦~
阅读全文
0 0
- c++::关于类型萃取
- 【C++】类型萃取
- 【C++】类型萃取
- c++:模板的类型萃取
- c++:模板的类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 【C++】类型萃取技术实现静态顺序表
- C++_模板类与类型萃取技术
- 商品唯一订单系列号生成简易算法
- 区块链--智能合约详解
- 堆和栈的区别
- Go 学习笔记
- 关于数组的 sizeof和strlen 的一些计算
- C++类型萃取
- 认识Lucene
- 树的同构(25 分)
- 异业合作出效果,联通一起沃再创新玩法
- 腾讯安全联队Pwn2Own黑客大赛5秒攻破苹果Safari获全额积分
- 科沃斯Smart Move技术产品亮相广州
- 劫持无人机?并非3•15晚会想象的那样简单
- Leetcode529. DFS之应用(三):解决扫雷游戏
- kafka与eclipse结合