小结 | C++模板的类型萃取
2018-02-24 17:25
309 查看
个人博客传送门
类型萃取,是C++中的一种编程技术。当我们希望对模板传递的不同类型进行不同的操作的时候,同时我们又不希望改变该模板的封装方式。我们可以通过这种技术,对传入的不同类型进行不同的原理操作。
特化
要明白类型萃取,首先要知道模板中的特化。一般来说,我们的模板是通用类型的,但是如果有一些类型,我们希望有不同的操作方式,我们就可以通过特化的方式。例子如下:
只有int类型才会输出int,其它的就像是float和char类型输出的都是number
特化的方式,其实是十分冗余的。如果我的number类有很多的封装,那么实现它的特化,就需要将这些封装重新实现一遍。这样的复用性就十分低。
类型萃取TypeTraits
关于类型萃取的知识,可以看看我的这篇读书笔记中的3.3和3.4
我的个人博客文章地址
我的CSDN博客文章地址
这里我进行一个对于自创类SeqList类(对STL中vector的模拟)的类型萃取举例,情景说明:这里我想要对模板类SeqList进行拷贝,涉及到一个问题。如果我的元素类型是string的话,我必须进行深拷贝,否则就会出现奔溃的情况,这是对内存的使用出现问题。当我的元素类型是int、float、char等平凡类型(即POD:plain old data,基本类型,这些类型的拷贝不会涉及到内存的使用异常),我就可以使用浅拷贝,这样比起深拷贝提高了效率。
这个时候,我通过在SeqList类中进行类型萃取,就可以实现两种不同的拷贝方式:
这样,当传入的参数是s1,s2的时候,
类型萃取,是C++中的一种编程技术。当我们希望对模板传递的不同类型进行不同的操作的时候,同时我们又不希望改变该模板的封装方式。我们可以通过这种技术,对传入的不同类型进行不同的原理操作。
特化
要明白类型萃取,首先要知道模板中的特化。一般来说,我们的模板是通用类型的,但是如果有一些类型,我们希望有不同的操作方式,我们就可以通过特化的方式。例子如下:
#include <iostream> using namespace std; //模板的一般版本 template <class T> class number{ public: void show(){ cout << "number" << endl; } }; //模板的int类型特化版本 template <> class number<int>{ public: void show(){ cout << "int" << endl; } }; int main(){ system("clear"); number<int> numint; numint.show(); number<float> numfloat; numfloat.show(); number<char> numchar; numchar.show(); return 0; }
只有int类型才会输出int,其它的就像是float和char类型输出的都是number
特化的方式,其实是十分冗余的。如果我的number类有很多的封装,那么实现它的特化,就需要将这些封装重新实现一遍。这样的复用性就十分低。
类型萃取TypeTraits
关于类型萃取的知识,可以看看我的这篇读书笔记中的3.3和3.4
我的个人博客文章地址
我的CSDN博客文章地址
这里我进行一个对于自创类SeqList类(对STL中vector的模拟)的类型萃取举例,情景说明:这里我想要对模板类SeqList进行拷贝,涉及到一个问题。如果我的元素类型是string的话,我必须进行深拷贝,否则就会出现奔溃的情况,这是对内存的使用出现问题。当我的元素类型是int、float、char等平凡类型(即POD:plain old data,基本类型,这些类型的拷贝不会涉及到内存的使用异常),我就可以使用浅拷贝,这样比起深拷贝提高了效率。
这个时候,我通过在SeqList类中进行类型萃取,就可以实现两种不同的拷贝方式:
//定义两个空类 struct __TrueType{}; struct __FalseType{}; //一般类型及特化(内嵌重定义IsPODType) template<class T> struct __TypeTraits{ typedef __FalseType IsPODType; }; template<> struct __TypeTraits<int>{ typedef __TrueType IsPODType; }; //实现功能函数(用__TrueType/__FalseType实现重载) template <class T> T* __TypeCopy(T* dst, const T* src, size_t n, __TrueType){ //浅拷贝,调用memcpy return (T*)memcpy(dst, src, n*sizeof(T)); } template <class T> T* __TypeCopy(T* dst, const T* src, size_t n, __FalseType){ //深拷贝,进行了 operator= 调用 for(size_t i = 0; i<n; ++i){ dst[i] = src[i]; } return dst; } //对外接口(实现IsPODType的__TrueType和__FalseType的转换) template <class T> T* TypeCopy(T* dst, const T* src, size_t n){ return __TypeCopy(dst, src, n, __TypeTraits<T>::IsPODType); } //调用 int main(){ int a1[3] = {1, 2, 3}; int a2[2] = {0, 0, 0}; string s1[3] = {"1", "2", "3"}; string s2[3] = {"0", "0", "0"}; TypeCopy(a1, a2, 3); TypeCopy(s1, s2, 3); return 0; }
这样,当传入的参数是s1,s2的时候,
__TypeTraits调用的是一般版本,
IsPODType为
__FalseType,这样
__TypeCopy调用的是
__FalseType的重载版本,进行深拷贝。当传入的参数是a1,a2的时候,调用的是
__TrueType的重载版本,进行浅拷贝。这里只对int进行了特化,所以只有int可以调用
__TrueType的版本。但是我们可以对float、double等PODType进行特化,这样就大大提高了代码的复用性。
相关文章推荐
- C++ 模板 之 类型萃取 与 容器适配器
- C++ 模板类型萃取技术 第一部分 为什么要有萃取技术
- c++ 类型萃取(模板类型 运用)
- C++ 模板类型萃取技术 第二部分 基于泛型的类型萃取技术
- 【C++】模板简述(五):类型萃取
- c++:模板的类型萃取
- c++:模板的类型萃取
- C++ 模板 之 类型萃取 与 容器适配器
- C++ 模板类型萃取技术 traits
- C++ 模板类型萃取技术
- C#调用C++版本dll时的类型转换需要注意的问题小结
- Dev-C++下基本数据类型学习小结
- 利用C++模板特性计算各整数类型的最大最小值
- 模板的类型萃取
- C++带模板结构体 类型重定义*
- c/c++ 基本类型学习小结
- 读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”
- 利用 c++模板 类型 推导思想,实现最简单的 判断两个类型 是否一样的 方法
- c++训练营--内联函数,c++类型转换,模板,异常捕获
- C++类型萃取