C++类型萃取
来源:互联网 发布:邮箱数据购买 编辑:程序博客网 时间:2024/04/30 02:01
在Seqlist中,我们对于内置类型,通过memcopy和memmove这两个方式进行拷贝,自定义类型或string类型我们要通过for循环赋值的方式拷贝。
那么系统如何区分是哪种类型呢?
虽然通过typeid可以获取变量类型,但是这样获取到的类型,无法用来做变量的声明。
因此,我们这里引入类型萃取。
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"template<class T>void Copy(T* dst, T* src, size_t size){ memcpy(dst, src, sizeof(T)*size);}int main(){ string s1[10] = { "123", "456", "7" }; string s2[10] = { "abc", "def", "g" }; Copy<string>(s1, s2, 10); return 0;}
从上面的Copy函数可以看出,拷贝的工作已经成功完成,但是在程序结束时崩溃了。
这是因为memcpy是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
对同一块内存析构多次,导致程序崩溃。
所以对于string类型的拷贝, 我们通过for循环来进行:
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"template<class T>void Copy(T* dst, T* src, size_t size){ //memcpy(dst, src, sizeof(T)*size); for (int i = 0; i < size; ++i) { dst[i] = src[i]; }}int main(){ string s1[10] = { "123", "456", "7" }; string s2[10] = { "abc", "def", "g" }; Copy<string>(s1, s2, 10); return 0;}
由上面的两种情况,我们可以看出,memcpy作为库函数,拥有很高的效率, 但是涉及到内存问题时,十分容易出错。
通过for循环的拷贝工作,不易出错,但是效率低。
两种拷贝方式各有各自的优势与劣势,对于不同的类型拷贝适合不同的拷贝方式,这里就用到了类型萃取。
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include "string"struct __TrueType{ static bool Get() { return true; }};struct __FalseType{ static bool Get() { return false; }};template <class _Tp>struct TypeTraits{ typedef __FalseType __IsPODType;};template <>struct TypeTraits< bool>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< char>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< unsigned char >{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< short>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< unsigned short >{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< int>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< unsigned int >{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< long>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< unsigned long >{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< long long >{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< unsigned long long>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< float>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< double>{ typedef __TrueType __IsPODType;};template <>struct TypeTraits< long double >{ typedef __TrueType __IsPODType;};template <class _Tp>struct TypeTraits< _Tp*>{ typedef __TrueType __IsPODType;};//// 使用参数推导的萃取处理//template <class T>void Copy(const T* src, T* dst, size_t size, __FalseType){ cout << "__FalseType:" << typeid(T).name() << endl; for (size_t i = 0; i < size; ++i) { dst[i] = src[i]; }}template <class T>void Copy(const T* src, T* dst, size_t size, __TrueType){ cout << "__TrueType:" << typeid(T).name() << endl; memcpy(dst, src, size*sizeof (T));}template <class T>void Copy(const T* src, T* dst, size_t size){ cout << "__TrueType:" << typeid(T).name() << endl; if (TypeTraits <T>::__IsPODType().Get()) { memcpy(dst, src, size*sizeof (T)); } else { for (size_t i = 0; i < size; ++i) { dst[i] = src[i]; } }}int main(){ string s1[10] = { "123", "456", "7" }; string s2[10] = { "abc", "def", "g" }; //Copy<string>(s1, s2, 10); return 0;}
0 0
- c++::关于类型萃取
- 【C++】类型萃取
- 【C++】类型萃取
- c++:模板的类型萃取
- c++:模板的类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 类型萃取
- 【C++】类型萃取技术实现静态顺序表
- C++_模板类与类型萃取技术
- python yield generator 详解
- CentOS7上安装Redis3.2.8
- 初级排序算法(选择排序+插入排序+希尔排序)动态可视化实现
- gunicorn syncworker 源码解析
- 深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手
- C++类型萃取
- 计算机网络体系结构
- 发布系统报错,SpringObjectFactory.java:220:-1,解决方法
- 作业题(dp)
- gunicorn 信号处理(SIGHUP,SIGUSR2)
- Java网络架构前言
- js创建对象的几种方式
- 深入浅出QOS详解
- 类的本质及其存储