Type Trait 和 Type Utility
所谓Type trait,提供了一种用来处理type 属性的办法,它是个template,可在编译期根据一个或多个template实参(通常也是type)产出一个type或者value。
template <typename T>
void foo(const T& val) {
if (std::is_pointer<T>::value) {
cout << "foo called for a pointer " << endl;
}
else
cout << "foo() called for a value" << endl;
//...
}
trait std::is_pointer定义于<type_traits>,用来检查T是否pointer type。若是,就是 type true_type,否则type false_type。而::value若非产生true就是false。
但是,不能如下这么做:
template <typename T>
void foo(const T& val) {
std::cout << (std::is_pointer<T>::value ? *val : val) << endl;
}
关键是不确定val到底是指针还是普通值。若是个值得话,*val 就无效了,不能通过编译。
template <typename T>
void fool_impl(const T& val,std::true_type){
cout << "foo() called for pointer to " << *val << endl;
} template<typename T>
void fool_impl(const T7 val, std::false_type){
cout << "foo() called value to "<< val << endl;
} template<typename T>
void foo(const T& val){
fool_impl(val,std::is_pointer<T>());
}
这比重载版本要好。是因为,有时候太多重载版本并无必要。一般而言,type trait 的威力来自于一个事实:它们是泛型代码的基石。
两个例子:
1 针对整数的弹性重载
假设一个函数foo(),对于整数类型和浮点类型的实参有不同的实现。通常做法是重载:
void foo(short);
void foo(unsigned short);
void foo(int);
...
void foo(float);
void foo(double);
void foo(long double);
每多一个类型,就需要一个新的重载函数。但是,有了type trait就是不一样:
template <typename T>
void foo_impl(T val, true_type); template<typename T>
void foo_impl(T val, false_type); template<typename T>
void foo(const T& val){
fool_impl(val,std::is_integral<T>());
}
只需提供两份实现,整数和浮点,完事儿。
2 处理共通类型
共通类型是一个可以“用来处理两个不同类型的值”的类型,前提是存在这个一个共通类型。举例而言,不同类型的两个值的总和或最小值,就该使用共通类型。
template<typename T1, typename T2>
typename std::common_type<T1,T2>::type min(const T1& x, const T2& T);
如果两个实参都是int 或者都是long,或者一个是int一个是long,std::common_type<T1,T2>::type 会产生int。如果实参之一是string而另一个是字符串字面常量,就产生std::string. 其通过以下规则实现:
template<typename T1, typename T2>
struct common_type<T1,T2>{
typedef decltype(true ? decval<T1>() : decval<T2>()) type;
};
其中 decltype是c++11提供的关键字,用以到处表达式类型,declval()是辅助性trait,依据传入的类型提供一个值 ,但是不去核算它。
该头文件下的函数等 。cppreference.com
Type Trait 和 Type Utility的更多相关文章
- input[type='submit']input[type='button']button等按钮在低版本的IE下面,去掉黑色边框的问题
今天做一个tabs效果的时候,发现上面的button在低版本下会出现黑色的边框,很难看,于是我整理了下几个去掉黑色边框的办法: 1.在button的外层嵌套一个div,设置button的border: ...
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的运行机理:1. ( (TYPE *)0 ) 将零转型为TY ...
- type和create type
type和create type 异同点: create type 可在库中生成一个长期有效的自定义类型对象,而type作用域仅限于语句块中: 两者都可以自定义数据类型: 各种ty ...
- There is no result type defined for type 'json' mapped with name 'success'. Did you mean 'json'?
错误信息: 严重: Exception starting filter struts2 Unable to load configuration. - action - file:/C:/Users/ ...
- form表单重复提交,type=“button”和type=“submit”区别
公司测试提了一个项目后台在IE浏览器下(360,firefox就没问题)出现数据重复的问题,调试了好久终于发现问题所在,也不知道是谁写的代码,醉醉的.... 错误地点: <input type= ...
- swift 中Value Type VS Class Type
ios 中Value Type 和 Class Type 有哪些异同点,这个问题是在微信的公共帐号中看到的,觉得挺有意思,这里梳理一下. 1.swift 中为什么要设置值类型? 值类型在参数传递.赋值 ...
- Failed to register Grid Infrastructure type ora.mdns.type
安装11g的集群软件的时候,在最后运行root.sh脚本时候,没有执行成功,最后提示如下错误: [root@r2 ~]# /u01/app/11.2.0/grid_1/root.sh Performi ...
- Springs Element 'beans' cannot have character [children], because the type's content type is element-only
Springs Element 'beans' cannot have character [children], because the type's content type is element ...
- Type I and type II errors | 第一类错误和第二类错误
偶尔能看懂,但是死活记不住,归根结底是没有彻底理解! Type I and type II errors - wiki type I error is the rejection of a true ...
随机推荐
- Web jsp开发学习——连接数据库,数据的增加和删除
1.首先在newlist界面增加三个图表,带上事件 newlist.jsp <%@ page language="java" contentType="text/h ...
- React Native中ref的用法(通过组件的ref属性,来获取真实的组件)
ref是什么? ref是组件的特殊属性,组件被渲染后,指向组件的一个引用.可以通过组件的ref属性,来获取真实的组件.因为,组件并不是真正的DOM节点,而是存在于内存中的一种数据结构,称为虚拟的DOM ...
- 英特尔® 图形性能分析器 2019 R1 版本
了解并下载全新英特尔® 图形性能分析器 2019 R1 版本.新版本新增了 DX11 和 Vulkan 多帧流捕获模式,可以在“帧和图形跟踪分析器”中分析 Vulkan 应用.此外,帧分析器还添加了 ...
- Django-MVC框架和MTV框架
MVC框架 全称Model View Controller,分为三个基本部分:模型Model.视图View和控制器Controller,具有耦合性低.重用性高.生命周期低等优点. 结构 View层,操 ...
- 【AMAD】stackprint -- 为Python加入利于调试的traceback信息
简介 动机 作用 用法 热度分析 源码分析 个人评分 简介 为Python加入利于调试的traceback信息.  动机 Python抛出异常时,会显示一些traceback信息.但是,一些时候这些 ...
- 字符串——AC自动机
目录 一.前言 二.思路 三.代码 四.参考资料 一.前言 以前一直没学AC自动机,主要是被名字吓到了,自动AC,这么强的名字肯定很难,学了后才发现,其实不难. AC自动机并不是Acept autom ...
- 论文翻译:LP-3DCNN: Unveiling Local Phase in 3D Convolutional Neural Networks
引言 传统的3D卷积神经网络(CNN)计算成本高,内存密集,容易过度拟合,最重要的是,需要改进其特征学习能力.为了解决这些问题,我们提出了整流局部相位体积(ReLPV)模块,它是标准3D卷积层的有效替 ...
- 【神经网络与深度学习】gflags介绍
gflags是什么: gflags是google的一个开源的处理命令行参数的库,使用c++开发,具备python接口,可以替代getopt. gflags使用起来比getopt方便,但是不支持参数的简 ...
- 【VS开发】关于内存泄漏的调试
没想到造成泄漏的原因是由于保存数据的线程因为事件阻塞在那里,此时要关闭OnClose的时候,这个挂起的线程爆出了内存泄漏,所以在关闭窗口之前,需要SetEvent(m_hSaveDataEvent); ...
- SolidWorks学习笔记5创建基准面,基准线,基准点
创建基准面 平面偏移方式 点击参考几何体,点击基准面 第一参考选中时,点击一个参考平面,粉色的 通过三个点 通过一个线和不在改线上的点 经过某一个点和某一个平面平行 一个平面绕一个轴(该轴平行或者在平 ...