所谓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的更多相关文章

  1. input[type='submit']input[type='button']button等按钮在低版本的IE下面,去掉黑色边框的问题

    今天做一个tabs效果的时候,发现上面的button在低版本下会出现黑色的边框,很难看,于是我整理了下几个去掉黑色边框的办法: 1.在button的外层嵌套一个div,设置button的border: ...

  2. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)宏的运行机理:1. ( (TYPE *)0 ) 将零转型为TY ...

  3. type和create type

    type和create type 异同点:      create type 可在库中生成一个长期有效的自定义类型对象,而type作用域仅限于语句块中:      两者都可以自定义数据类型: 各种ty ...

  4. 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/ ...

  5. form表单重复提交,type=“button”和type=“submit”区别

    公司测试提了一个项目后台在IE浏览器下(360,firefox就没问题)出现数据重复的问题,调试了好久终于发现问题所在,也不知道是谁写的代码,醉醉的.... 错误地点: <input type= ...

  6. swift 中Value Type VS Class Type

    ios 中Value Type 和 Class Type 有哪些异同点,这个问题是在微信的公共帐号中看到的,觉得挺有意思,这里梳理一下. 1.swift 中为什么要设置值类型? 值类型在参数传递.赋值 ...

  7. Failed to register Grid Infrastructure type ora.mdns.type

    安装11g的集群软件的时候,在最后运行root.sh脚本时候,没有执行成功,最后提示如下错误: [root@r2 ~]# /u01/app/11.2.0/grid_1/root.sh Performi ...

  8. 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 ...

  9. Type I and type II errors | 第一类错误和第二类错误

    偶尔能看懂,但是死活记不住,归根结底是没有彻底理解! Type I and type II errors - wiki type I error is the rejection of a true  ...

随机推荐

  1. windows 重启java进程脚本

    这个脚本用于启动和重启javaWeb程序 @echo off rem 配置端口号 set port= rem 第一层循环检查端口占用的pid for /f "tokens=5" % ...

  2. Angularjs E2E test Report/CoverageReport

    前端Angularjs是一个很热门的框架,这篇是学习基于Angularjs的nodejs平台的E2E测试报告和E2E JS覆盖率报告.用到的都是现有的工具,只是一些配置的地方需要注意. 环境前提: 1 ...

  3. TYPES与DATA区别

    例如:int  a; "c语言定义 TYPES:BEGIN OF typ,   filed1 TYPE c,   END OF typ.         "相当于int类型 DAT ...

  4. ModelAndView及页面转发

    1.ModelAndView springMVC中返回值如果是ModelAndView,则其既包含模型数据信息,也包含视图信息. 在处理方法中可以使用ModelAndView对象的方法添加模型数据:a ...

  5. 什么是maven?maven中的pom文件是做什么的?

    Maven 是专门用于构建和管理Java相关项目的管理工具. 1.使用Maven管理的Java 项目都有着相同的项目结构 2.统一维护jar包 POM是项目对象模型(Project Object Mo ...

  6. Windows下的开发辅助神器——Chocolate Package Manager

    Windows下的开发辅助神器——Chocolate Package Manager:https://juejin.im/post/5c6cb3acf265da2dc4537235 Windows上的 ...

  7. 好用的 Chrome 插件

    这些好用的 Chrome 插件,提升你的工作效率   本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可 ...

  8. layer ajax请求

    layer ajax请求 $.ajax({ // url: '../php/creatSceneXml.php', url: '../php/action.php', type: 'POST', da ...

  9. 2019icpc南昌邀请赛F(线段树)

    题目链接:https://nanti.jisuanke.com/t/40258 题意:给长为n的数组a,有m次操作,包括单点修改和查询F(l,r),其值为所有f(i,j)的异或和,l<=i< ...

  10. Docker 运行的 应用程序无法连接Oracle数据库的解决办法

    1. 最近公司使用docker化部署运行 app  发现一个部门的 多数据源取数的功能连接不上 oracle数据库 报错提示为: 2. 公司平台部同事给出两个解决方案: https://blog.cs ...