C++11模板元编程—std::enable_if使用说明
std::enable_if
顾名思义,满足条件时类型有效。作为选择类型的小工具,其广泛的应用在 C++ 的模板元编程中。它的定义也非常的简单:
// STRUCT TEMPLATE enable_if
template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Testtemplate <class _Ty>
struct enable_if<true, _Ty> { // type is _Ty for _Testusing type = _Ty;
};
由此可知,只有当第一个模板参数_Test
为 true
时,type
才有定义(type
即第二个模板参数_Ty
);否则使用 type
会产生编译错误,且默认模板参数可以让你不必指定类型。
另外enable_if_t
是一个别名,其定义如下:
template <bool _Test, class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;
std::enable_if
可以用作函数参数、返回类型或类模板或函数模板参数,以有条件地从重载中删除函数或类。
一、作为函数参数
template<typename T>
struct Check1
{//如果T的类型是int,则定义函数 int read(void* = nullptr)template<typename U = T>U read(typename std::enable_if_t<std::is_same_v<U, int> >* = nullptr) {return 42;}//如果T的类型是double,则定义函数 double read(void* = nullptr)template<typename U = T>U read(typename std::enable_if_t<std::is_same_v<U, double> >* = nullptr) {return 3.14;}
};
使用示例
Check1<int> c1;
int x1 = c1.read();Check1<double> c2;
double x2 = c2.read(0);
二、作为模板参数
template<typename T>
struct Check2
{//如果T的类型是int,则定义函数 int read()template<typename U = T, typename std::enable_if_t<std::is_same_v<U, int>, int> = 0>U read() {return 42;}//如果T的类型是double,则定义函数 double read()template<typename U = T, typename std::enable_if_t<std::is_same_v<U, double>, int> = 0>U read() {return 3.14;}
};
也可以写成如下形式:
template<typename T>
struct Check2
{template<typename U = T, typename std::enable_if_t<std::is_same_v<U, int>>* = nullptr>U read() {return 42;}template<typename U = T, typename std::enable_if_t<std::is_same_v<U, double>>* = nullptr>U read() {return 3.14;}
};
三、作为返回值类型
对于模板函数,有时希望根据不同的模板参数返回不同类型的值。
template<typename T>
struct Check3
{//如果T的类型是int,则定义函数 int read()template<typename U = T>typename std::enable_if_t<std::is_same_v<U, int>, U> read() {return 42;}//如果T的类型是double,则定义函数 double read()template<typename U = T>typename std::enable_if_t<std::is_same_v<U, double>, U> read() {return 3.14;}
};
利用auto关键字,可以写为如下形式:
// int goo<true>(int x)
template<bool B>
auto goo(int x) -> std::enable_if_t<B, int>
{return 1;
}// int goo<false>(int x)
template<bool B>
auto goo(int x) -> std::enable_if_t<!B, int>
{return 2;
}
四、类型偏特化
在使用模板编程时,经常会用到根据模板参数的某些特性进行不同类型的选择,或者在编译时校验模板参数的某些特性。例如:
// T是其它类型
template<typename T, typename = void>
struct zoo;// 如果T是浮点类型
template<typename T>
struct zoo<T, std::enable_if_t<std::is_integral_v<T>>>
{};
五、concepts
C++20中利用concepts可以简化编写方式:
#ifdef __cpp_lib_concepts
#include <concepts>
#endif// 如果T是整数类型
template<std::integral T>
void display_concepts_1(T num)
{}// 如果T是整数类型
void display_concepts(std::integral auto num)
{}// 如果T是浮点数类型
void display_concepts(std::floating_point auto num)
{}
等价于如下形式:
// 如果T是整数类型
template<typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
void display_1(T num)
{}// 如果T是整数类型
template<typename T>
void display(typename std::enable_if_t<std::is_integral_v<T>>* = nullptr)
{}// 如果T是浮点数类型
template<typename T>
void display(typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr)
{}
C++11模板元编程—std::enable_if使用说明相关推荐
- 基于C++11模板元编程实现Scheme中的list及相关函数式编程接口
前言 本文将介绍如何使用C++11模板元编程实现Scheme中的list及相关函数式编程接口,如list,cons,car,cdr,length,is_empty,reverse,append,map ...
- C++11模版元编程的应用
1.概述 关于C++11模板元的基本用法和常用技巧,我在程序员2015年2月B<C++11模版元编程>一文(后称前文)中已经做了详细地介绍,那么C++11模版元编程用来解决什么实际问题呢, ...
- 【C++ 泛型编程 进阶篇】:用std::integral_constant和std::is_*系列深入理解模板元编程
C++ 元模版编程:用std::integral_constant和std::is_*系列深入理解模板元编程 一.模板元编程与类型特性 (Template Metaprogramming and Ty ...
- 现代C++模板元编程基础
元函数的基础介绍 C++的模板元编程是函数式编程,所以函数是一等公民.一切在编译期间执行的函数都可以称为元函数.元函数有struct和constexpr两种定义方式,前者是一直使用的,后者是C++11 ...
- 模板元编程实现素数判定
模板元编程(英语:Template metaprogramming:缩写:TMP)是一种元编程技术,不夸张的说,这项技术开启了一种新的C++编程方式.编译器使用模板产生暂时性的源码,然后再和剩下的源码 ...
- C++ 模板元编程简介
文章目录 1.概述 2.模板元编程的作用 3.模板元编程的组成要素 4.模板元编程的控制逻辑 4.1 if 判断 4.2 循环展开 4.3 switch/case 分支 5.特性.策略与标签 6.小结 ...
- 闭关之 C++ 函数式编程笔记(四):monad 和 模板元编程
目录 第十章 monad 注意 10.1 仿函数并不是以前的仿函数 10.1.1 处理可选值 10.2 monad: 更强大的仿函数 10.3 基本的例子 10.4 range 与 monad 的嵌套 ...
- C++高阶必会操作--模板元编程
泛型编程大家应该都很熟悉了,主要就是利用模板实现"安全的宏",而模板元编程区别于我们所知道的泛型编程,它是一种较为复杂的模板,属于C++的高阶操作了,它最主要的优点就在于把计算过程 ...
- C++模板元编程详细教程(之五)
前序文章请看: C++模板元编程详细教程(之一) C++模板元编程详细教程(之二) C++模板元编程详细教程(之三) C++模板元编程详细教程(之四) STL中提供的工具 从这一篇开始,我们将正式介绍 ...
最新文章
- 相机原理updateTexImage
- c语言节点有指针域数据域,学习心得:链表的操作(C语言实现)
- linux vnc 屏幕大小,Linux系统下vnc 的配置和使用方法
- @getmapping注解的作用_一口气说出6种,@Transactional注解的失效场景
- thinkcmf 横向排列数据_利用python进行数据分析之数据清洗规整
- [vue] 你知道style加scoped属性的用途和原理吗?
- java质数判断程序_java判断一个数是否为素数/质数
- MediaPlayer控件的初探
- (转)RabbitMQ学习之安装
- 腾讯拟全资收购搜狗;英特尔人事大变动,首席工程官将离职;TensorFlow 2.3.0 正式发布 | 极客头条
- php中array_flip数组翻转
- python queue的用法_PYTHON多进程用法之四(Queue)
- android视频添加特效,抖音蝴蝶翅膀特效怎么弄的 安卓手机上给视频加蝴蝶特效的方法...
- 【MySQL】黑马教程MySQL数据库 MySQL基础(二)
- 你应该怎么样活着才有意思
- Elasticsearch系列—倒排索引原理
- 百度图片批量下载助手
- 将swolidwroks文件导出URDF,导入v-rep\CoppeliaSim
- 人生感悟:欲望适度则为利,欲望过度则为害,高级java开发工程师简历
- 設計模式之Visitor
热门文章
- 『david_lv』老朋友喜相逢 《走出软件作坊》也喜相逢-SD2.0大会第一天
- Solidworks进阶之路
- Ubuntu20.04 安装HPC_SDK加速库
- Ceph MDS问题分析
- 微信小程序毕业设计选题和毕业论文怎么写,答辩流程是怎样的?
- c语言程序设计山东联盟第三章答案,C语言程序设计(山东联盟)知到章节测试答案...
- 正确的使用dd进行磁盘读写速度测试
- 麒麟高级服务器版V10 SP1 yum 源 龙芯 loongarch64
- 带头结点单链表逆置的四种方法思路和实现
- php对接花呗,对接 花呗分期 不支持问题