https://yixinglu.gitlab.io/enable_if.html

std::enable_if 的几种用法
tech 12cpp 2
std::enable_if 顾名思义,满足条件时类型有效。作为选择类型的小工具,其广泛的应用在 C++ 的模板元编程(meta programming)中。它的定义也异常的简单:

template <bool, typename T=void>
struct enable_if {
};

template
struct enable_if<true, T> {
using type = T;
};
由上可知,只有当第一个模板参数为 true 时,type 才有定义,否则使用 type 会产生编译错误,并且默认模板参数可以让你不必指定类型。下面说说它的几种使用方法:

用法一:类型偏特化
在使用模板编程时,经常会用到根据模板参数的某些特性进行不同类型的选择,或者在编译时校验模板参数的某些特性。例如:

template <typename T, typename Enable=void>
struct check;

template
struct check<T, typename std::enable_if<T::value>::type> {
static constexpr bool value = T::value;
};
上述的 check 只希望选择 value==true 的 T,否则就报编译时错误。如果想给用户更友好的提示,可以提供结构体的原型定义,并在其中进行 static_assert 的静态检查,给出更明确的字符串说明。

用法二:控制函数返回类型
对于模板函数,有时希望根据不同的模板参数返回不同类型的值,进而给函数模板也赋予类型模板特化的性质。典型的例子可以参看 tuple 的获取第 k 个元素的 get 函数:

template <std::size_t k, class T, class… Ts>
typename std::enable_if<k==0, typename element_type_holder<0, T, Ts…>::type&>::type
get(tuple<T, Ts…> &t) {
return t.tail;
}

template <std::size_t k, class T, class… Ts>
typename std::enable_if<k!=0, typename element_type_holder<k, T, Ts…>::type&>::type
get(tuple<T, Ts…> &t) {
tuple<Ts…> &base = t;
return get(base);
}
由于函数模板不能偏特化,通过 enable_if 便可以根据 k 值的不同情况选择调用哪个 get,进而实现函数模板的多态。

用法三:校验函数模板参数类型
有时定义的模板函数,只希望特定的类型可以调用,参考 cppreference 官网示例,很好的说明了如何限制只有整型可以调用的函数定义:

template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T t) {return bool(t%2);
}template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even(T t) {return !is_odd(t);
}

一个通过返回值,一个通过默认模板参数,都可以实现校验模板参数是整型的功能。

std::enable_if 的几种用法相关推荐

  1. SNIFE 和 std::enable_if

    类型基础 在回顾模板之前,需要明确一个概念:模板编程是针对类型的计算..这和我们平时的代码不同,我们平时写的程序都是针对数据的. 在模板元编程中,typename 用于定义类型:using 用于给模板 ...

  2. std::enable_if的用法

    一.测试程序1 #include <iostream> #include <type_traits> using namespace std; template <typ ...

  3. std::enable_if

    std::enable_if 顾名思义,满足条件时类型有效.作为选择类型的小工具,其广泛的应用在 C++ 的模板元编程(meta programming)中.它的定义也异常的简单: template ...

  4. c++11 std::enable_if在模板偏特化的妙用

    1.模板自动推导功能. 先看个例子: 在调用TestTemplate函数时, 我们可以在函数后面加上<类型>无歧义地指定调用的版本. 结果如下: 由于模板参数在函数参数中的位置是固定的,编 ...

  5. static的三种用法,定义静态变量,静态函数,静态代码块!

    static的三种用法,定义静态变量,静态函数,静态代码块! 1.定义静态变量 class PersonStatic { //静态变量的特点 //1.静态变量无需生成对象就可被调用,可以使用类名和对象 ...

  6. 【C++】41. std::copy和assign的用法

    对于std::copy的用法,可以参考 https://blog.csdn.net/a_ran/article/details/17385911,我这里直接介绍对于std::vector来说std:: ...

  7. c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast...

    C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...

  8. C++ 命名空间三种用法

    C++ 命名空间三种用法 1.#include <iostream> using namespace std; //直接using会把整个空间里的东西全部引入,这样做的优点是省事,缺点是如 ...

  9. c++中using的几种用法

    最近在使用中,发现了一种以前没学过的using用法,于是在这里,将using的几种用法总结一下. 先来说说我新学会的一种用法,就是起别名,我们都知道typedef可以给我们起别名,using也可以,用 ...

最新文章

  1. mysql导入Excel数据
  2. python怎么安装numpy库-Python NumPy库安装使用笔记
  3. 快消行业指的是哪些?
  4. RTSP学习笔记(2)live555
  5. 单表数据量过大处理策略
  6. Spring用户自定义类型
  7. java excel条件格式_Java 设置Excel条件格式(高亮条件值、应用单元格值/公式/数据条等类型)...
  8. ffmpeg将sdp转发_ffmpeg常用命令
  9. 强悍的 Vim —— .vimrc(vim 配置文件)
  10. 非常经典的java编程题全集-共50题(1-10)
  11. 怎么做电商详情页html,电商商品详情页怎么做?电商详情页模板一键生成的方法...
  12. android微信版本怎么升级,微信版本怎么看 微信版本升级更新至最新版本方法介绍...
  13. 怎样用Python自制好看的指数估值图
  14. 爬取百度文库内容(Selenium+BeautifulSoup)
  15. 【21世纪电脑入门】总目录——系统配置、包/库安装、问题修复
  16. 关于Rasa你必须要知道的几件事
  17. 6.18电子书5折促销
  18. opencv与python环境搭建
  19. 监控FTP服务状态,并自动重启servU
  20. 真正的手机密码大全!(完整版)(转)

热门文章

  1. 2022年陕西省安全保护服务人员(初级保安员)考试练习题及答案
  2. 抖音SEO是什么?该怎么做?如何使用抖音seo实施推广
  3. js去除字符串中的空格
  4. Linux虚拟化技术
  5. 盘点算法优化在物流行业的典型应用案例
  6. 中国三氟乙醇行业研究与投资预测报告(2022版)
  7. Camtasia2021最新版电脑PC录制屏幕新增功能介绍
  8. destoon 标签
  9. 能力才是女人最极致的性感
  10. 安卓ListView选中后保持高亮状态,且两级联动带图标(升级版)