C++类型萃取
来源:互联网 发布:优化发展环境讲话 编辑:程序博客网 时间:2024/06/06 18:41
一.问题的引入
首先我们如果要写一个拷贝函数,代码如下:
template<class T>void Copy(T *dst, T *src, size_t size){memcpy(dst, src, sizeof(T)*szie);}
但是这个代码拷贝内置类型的没有问题,但是如果是自定义类型的,就牵扯到深浅拷贝问题,就行不通了,所以我们需要做的就是在代码内部判断传过来的数据类型,从而进行不同的操作。代码如下
template<class T>void Copy(T *dst, T *src, size_t size){if (内置类型){memcpy(dst, src, sizeof(T)*size);}else//自定义类型{for (size_t i = 0; i < size; ++i)dst[i] = src[i];}}但是怎么进行类型判断呢?代码如下:
bool IsPOD(const char *TypeName){static char *p[] = { "int", "double", "float" };int len = sizeof(p) / sizeof(*p);for (int i = 0; i < len; ++i){if (strcmp(p[i], TypeName) == 0)//为自定义类型返回truereturn true;}return false;}这样的话我们只需要在Copy的函数if语句中调用这个IsPOD函数就可以区分自定义类型和内置类型了,从而解决了之前类型不同的问题。
完整的代码如下:
bool IsPOD(const char *TypeName){static char *p[] = { "int", "double", "float" };int len = sizeof(p) / sizeof(*p);for (int i = 0; i < len; ++i){if (strcmp(p[i], TypeName) == 0)//为自定义类型返回truereturn true;}return false;}template<class T>void Copy(T *dst, T *src, size_t size){if (IsPOD(typeid(T).name())){memcpy(dst, src, sizeof(T)*size);}else{for (size_t i = 0; i < size; ++i)dst[i] = src[i];}}int main(){int a1[] = { 1, 2, 3, 4, 5 };int a2[5];string s1[] = { "1111", "2222", "3333", "4444" };string s2[4];Copy(a2, a1, sizeof(a1) / sizeof(*a1));Copy(s2, s1, sizeof(s1) / sizeof(s1[0]));system("pause");return 0;}二.类型萃取
类型萃取的功能和上述代码一样,就是用来提取代码类型的,不过具体的实现步骤是什么样的呢,我们继续往下看
首先给出如下代码
struct TrueType{static bool IsPODType(){return true;}};struct FalseType//对应自定义类型的处理{static bool IsPODType(){return false;}};//什么类型都可以处理template<class T>//所有的类型都扔进去处理struct TypeTraits{typedef FalseType PODtype;//将数据类型看成自定义的类型来处理不会出错};相信这段代码有一定基础的同学一定可以看懂,接下来看Copy中如何使用上面的模版
template<class T>void Copy(T *dst, T *src, size_t size){if (TypeTraits<T>::PODtype::IsPODType()){memcpy(dst, src, sizeof(T)*size);}else{for (size_t i = 0; i < size; ++i)dst[i] = src[i];}}但是这样无法识别自定义类型和内置类型,因为无论扔过去什么都会返回false,怎么解决这个问题呢,这就要用到模版的特化
代码如下:
//什么类型都可以处理template<class T>//所有的类型都扔进去处理struct TypeTraits{typedef FalseType PODtype;//将数据类型看成自定义的类型来处理不会出错};template<>struct TypeTraits<int>{typedef TrueType PODtype;};template<>struct TypeTraits<char>{typedef TrueType PODtype;};template<>struct TypeTraits<double>{typedef TrueType PODtype;};这样的话就可以处理不同的类型的
下面给出完整的代码包括测试代码:
struct TrueType{static bool IsPODType(){return true;}};struct FalseType//对应自定义类型的处理{static bool IsPODType(){return false;}};//什么类型都可以处理template<class T>//所有的类型都扔进去处理struct TypeTraits{typedef FalseType PODtype;//将数据类型看成自定义的类型来处理不会出错};template<>struct TypeTraits<int>{typedef TrueType PODtype;};template<>struct TypeTraits<char>{typedef TrueType PODtype;};template<>struct TypeTraits<double>{typedef TrueType PODtype;};template<class T>void Copy(T *dst, T *src, size_t size){if (TypeTraits<T>::PODtype::IsPODType()){memcpy(dst, src, sizeof(T)*size);}else{for (size_t i = 0; i < size; ++i)dst[i] = src[i];}}int main(){int a1[] = { 1, 2, 3, 4, 5 };int a2[5];string s1[] = { "1111", "2222", "3333", "4444" };string s2[4];Copy(a2, a1, sizeof(a1) / sizeof(*a1));Copy(s2, s1, sizeof(s1) / sizeof(s1[0]));system("pause");return 0;}下面给出内定类型的执行过程,因为自定义类型和内置类型的执行过程和原理一样,下面可以自己去测试
以上就是类型萃取,其实就是模版的特化的应用!
其实上面的完整类型萃取也可以写成如下的方式,代码如下:
struct TrueType{};struct FalseType//对应自定义类型的处理{};//什么类型都可以处理template<class T>//所有的类型都扔进去处理struct TypeTraits{typedef FalseType PODtype;//将数据类型看成自定义的类型来处理不会出错};template<>struct TypeTraits<int>{typedef TrueType PODtype;};template<>struct TypeTraits<char>{typedef TrueType PODtype;};template<>struct TypeTraits<double>{typedef TrueType PODtype;};template<class T>void Copy(T *dst, T *src, size_t size, TrueType){memcpy(dst, src, sizeof(T)*size);}template<class T>void Copy(T *dst, T *src, size_t size, FalseType){for (size_t i = 0; i < size; ++i)dst[i] = src[i];}template<class T>void Copy(T *dst, T *src, size_t size){Copy(dst, src, size, TypeTraits<T>::PODtype());}int main(){int a1[] = { 1, 2, 3, 4, 5 };int a2[5];string s1[] = { "1111", "2222", "3333", "4444" };string s2[4];Copy(a2, a1, sizeof(a1) / sizeof(*a1));Copy(s2, s1, sizeof(s1) / sizeof(s1[0]));system("pause");return 0;}
阅读全文
0 0
- c++::关于类型萃取
- 【C++】类型萃取
- 【C++】类型萃取
- c++:模板的类型萃取
- c++:模板的类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 【C++】类型萃取技术实现静态顺序表
- C++_模板类与类型萃取技术
- 【JDBC笔记】第三方连接池:DBCP/C3P0
- 引用和指针
- SOCKET中send和recv函数真正在做什么
- 位运算符说明
- ORA-01219:数据库未打开:仅允许在固定表/视图中查询
- C++类型萃取
- java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总
- Maven工程启动时出现 Unable to compile class for JSP错误
- Windows环境的GNU安装以及使用makefile编译生成*.exe
- c++知识点总结七
- fiddler对浏览器、app抓包及证书安装
- nowcode Cut(Wannafly挑战赛1 E)
- JAVA_位运算符_含义
- 设计模式_21:中介者模式