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. 清华AI学堂班:姚期智担任首席教授,2019年首批招收30人
  2. eclipse自定义快捷键
  3. 云炬Android开发笔记 14 个人中心、图片裁剪、图片上传、收货地址、消息推送、权限管理等功能开发与一键式封装
  4. OpenCV camshift算法的实例(附完整代码)
  5. Redis中的可用性保证之Sentinel 原理
  6. PL/SQL之高级篇
  7. 那些有趣的电子漫画合集
  8. Leetcode--442. 数组中重复的数据
  9. gevent版TCP服务器
  10. 薪资不如 Java、C,BAT 需求大,揭秘 Python 程序员跳槽现状!
  11. spring4.0.0的配置和使用
  12. 一篇文章学懂ADB命令和Monkey命令
  13. python怎么算二元一次方程_利用Python求解二元一次方程
  14. 【Android测试】在AndroidStudio中进行单元测试
  15. html用css设置图片大小,css如何设置图片大小?
  16. 财会法规与职业道德【9】
  17. 【设计模式 三】实战工厂汽车代工之工厂模式-简单模式
  18. SharedPreferences in credential encrypted storage are not available until after user is unlocked
  19. GBase 8c产品高级特性介绍
  20. Go语言如何高效的进行字符串拼接(6种方式进行对比分析)

热门文章

  1. 年轻人创新创业新理念
  2. deepin linux 安装教程,如何安装Deepin Linux?Deepin Linux安装体验
  3. java并发编程:多线程基础
  4. 使用layuimini模块快速开发java后台系统模板(前后端分离)
  5. 上下行速率和带宽的关系
  6. 中国麻纺织行业深度调查与投资潜力分析报告
  7. [论文阅读笔记15]GNN在多目标跟踪中的应用
  8. 《计算机视觉》集大网课笔记【2】
  9. python apply函数_python玄学之 apply函数的axis参数
  10. usaco1.1坏掉的项链