c++之类型萃取

刚刚我们接触过模板类,类似于这样的:


在这个类中,我们如何知道它是什么类型的呢?这里,我们可以在类中加入一个内嵌类型,如:


这样就可以知道它是用户自定义的还是本身类型就拥有的,我们用到了类型萃取的方式。我们把__IsPodType叫做内嵌型别。

当我们遇到其他类型时,就将__IsPodType定义为__FalseType;


当遇到自定义类型时,就将__IsPodType定义为__TrueType;

说起这种书写方式,将template<>称为类型的特化。

举一个实在点的例子吧微笑

#include<iostream>
using namespace std;
struct __TrueType
{bool Get(){return true;}
};struct __FalseType
{bool Get(){return false;}
};template<class __Tp>
struct TypeTraits
{typedef __FalseType __IsPodType;
};template<>
struct TypeTraits<int>                //在这里,非自定义类型只列出了int,char,float等这几种,其实还有很多类型,像long long,double,unsigned char等等
{typedef __TrueType __IsPodType;
};template<>
struct TypeTraits<char>
{typedef __TrueType __IsPodType;
};template<>
struct TypeTraits<long>
{typedef __TrueType __IsPodType;
};template<>
struct TypeTraits<unsigned int>
{typedef __TrueType __IsPodType;
};template<>
struct TypeTraits<float>
{typedef __TrueType __IsPodType;
};template<class __Tp>
void Copy(const __Tp* src, __Tp* dst,size_t size,__TrueType)
{memcpy(dst,src,size*sizeof(__Tp));      //拷贝的内置类型
}template<class __Tp>
void Copy(const __Tp* src, __Tp* dst,size_t size,__FalseType)
{int i = 0;for(i = 0; i < size; i++){dst[i] = src[i];}
}
<span style="font-family: Arial, Helvetica, sans-serif;">// 使用萃取判断类型的Get函数判断是否是 POD类型来处理</span>
//template<class __Tp>
//void Copy(const __Tp* src, __Tp* dst,size_t size)        //Copy的另外一种写法,不传入类型
//{
//	if(TypeTraits<__Tp>::__IsPodType().Get())          //if判断就可以直接写一个函数,,是上述两个Copy的结合
//	{
//		memcpy(dst,src,size*sizeof(__Tp));
//	}
//	else
//	{
//		int i = 0;
//		for(i = 0; i < size; i++)
//		{
//			dst[i] = src[i];
//		}
//	}
//}template<class __Tp>
void print(const __Tp* arr,size_t size)
{int i = 0;for(i = 0; i < size; i++){cout<<arr[i]<<" ";}
}int main()
{int arr1[] = {1,3,5,7,9};int arr2[10];int size = sizeof(arr1)/sizeof(arr1[0]);Copy(arr1,arr2,size,TypeTraits<int>::__IsPodType());/*Copy(arr1,arr2,size);*/print(arr2,size);return 0;
}

以上是数组的拷贝,用了类型萃取的方式。详细一点说类型萃取技术的由来就是,由于c++模板中类的参数是抽象的,我们不能在模板类中直接获得它的具体特征,我们就用类型萃取(trait)的方式,来抽取类型的具体特征,知道它是什么类型,比如内置类型,自定义类型。

我们可以看到很多模板类的特化,这也是类型萃取的一个基本思想。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382851.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

django xadmin出现的问题

1.File “/home/yuanqi/.virtualenvs/djangodev1/lib/python3.5/site-packages/xadmin/sites.py”, line 9, in reload(sys) import importlib importlib.reload(sys)# sys.setdefaultencoding("utf-8")把相应文件改为上述这样

一道面试题--两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同

1.问题说明 十进制4 0100 十进制8 1000二进制不同的 0100 1000有两位不同 正常的算法 1.两个数字与1&#xff0c;拿出两个数字的最后一位&#xff0c;比较是否相同&#xff0c;直到右移32次&#xff0c; for (int i 0; i < 32; i){if ((m & 1) ! (n & 1)){count…

时间复杂度空间复杂度

我们编过不少代码&#xff0c;起初学习的时候我们习惯性的认为&#xff0c;只要代码能正确的运行就ok啦~很少考虑代码的优化带来的好处。今天说一下影响代码性能的两个重要指标--时间复杂度&空间复杂度。 时间复杂度&#xff1a;就是函数&#xff08;指数学中的函数&#…

C语言 函数递归例题解析

1.接受一个整形值&#xff08;无符号&#xff09;&#xff0c;把它转换为 字符并打印它模拟实现strlen()函数。3.求n的阶乘4.斐波那契数列总结 1.接受一个整形值&#xff08;无符号&#xff09;&#xff0c;把它转换为 字符并打印它 void fun(int x) {if (x > 9){fun(x/10)…

xpath 简单用法小记

1 xpath定位 没有某个属性的元素 例如定位没有class属性的td tds tr.xpath(.//td[not(class)])

剖析printf函数

printf是什么&#xff0c;对于起初学习c语言的同学来说肯定都特别的疑惑。在这里&#xff0c;解答一下&#xff1a;它是一个函数。既然是一个函数的话&#xff0c;想必肯定有返回值和参数吧。那么它的返回值和参数是什么呢&#xff1f; 1、看一下这个例子&#xff0c;可能更好…

大端小端详解

文章目录为什么有大端小端&#xff1f;大端&#xff1a;低位放在高地址&#xff0c;高位放在低地址小端&#xff1a;低位放在低地址&#xff0c;高位放在高地址面试考点&#xff1a;代码代码2一道面试题为什么有大端小端&#xff1f; 大端&#xff1a;低位放在高地址&#xff0…

xpath 简单小记

1 定位没有class属性的td元素 tds tr.xpath(.//td[not(class)])

详解volatile关键字

volatile字面意思&#xff1a;易变的。在计算机里&#xff0c;是防止优化的意思&#xff0c;然而是怎么防止优化的呢&#xff1f;待我一一道来哦。 先看这样一个例子&#xff1a; <span style"font-size:18px;">#include<iostream> using namespace std…

C语言 有符号字符型输出 面试题

1.第一题 int main() {int a 128;printf("%u\n", a);system("pause"); } 输出结果 128 #include <stdio.h> #include <stdlib.h>int main() {char a 128;printf("%u\n", a);system("pause"); } 输出结果 42949671…

正则表达式提取括号里面的值

转自 https://blog.csdn.net/jiahaowanhao/article/details/80795148

有趣的链表相关题型

链表&#xff1a;也是线性表的一种。形象的来说&#xff1a; 就像火车的一个个车厢一样&#xff0c;一个个的链起来的。它有一个特点&#xff1a;它的头没有前驱&#xff0c;尾没有后继。 为什么会引入链表这个概念呢&#xff1f;之前我们知道的顺序表&#xff0c;是用数组的形…

简陋版C语言仿真通讯录

文件cotact.c #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include "contact.h" /*初始化*/ void InitContact(pContact pc) {pc->count 0;memset(pc->data, 0, sizeof(pc->data)); }/*增加数据*/ void AddCon…

pip3 便捷安装包

将虚拟环境下 的包列举出来 并保存到文件夹 pip3 freeze > requirments.txt 一次性安装文件里面所列举的所有的包 pip3 install -r requirments.txt

有趣的约瑟夫环问题

大家有没有听过约瑟夫环这个问题呢&#xff1f;我们先来看看它是一个什么样的问题~ 约瑟夫环&#xff08;Josephus&#xff09;问题是由古罗马的史学家约瑟夫&#xff08;Flavius Josephus&#xff09;提出的。该问题的说法不一&#xff0c;传说他参加并记录了公元66—70年犹太…

C语言模拟实现标准库函数之qsort() 2

C语言模拟实现标准库函数之qsort() <1> https://blog.csdn.net/csdn_kou/article/details/80158194 排序数字 int int_cmp(const void *elem1, const void *elem2) { return *(int *)elem1 - *(int *)elem2; }int main() { int arr[] { 9,8,7,6,5,4,3,2,1 }; int siz…

node.js windows下安装与配置

转自 https://www.cnblogs.com/liuqiyun/p/8133904.html

一系列链表题

1、链表的倒序输出&#xff1a;(输出4&#xff0c;3&#xff0c;2&#xff0c;1)在这里&#xff0c;可以使用递归的方式&#xff1a; <span style"font-size:18px;">void Reverse(pNode pHead) {if(pHead){Reverse(pHead->next);cout<<pHead->data…

简陋版C语言仿真通讯录之动态内存开辟版本

简陋版C语言仿真通讯录 https://blog.csdn.net/csdn_kou/article/details/80287640 简陋版C语言仿真通讯录之动态内存开辟版本 给Contact结构体增加一个容量&#xff0c;来表示什么时候增容 #define MAX_NAME 20 typedef struct PeoInfo {char name[MAX_NAME];int age;char …