今天看confluo源码中看到了std::enable_if这一个我不了解的语法,所以记录下来

转载地址:https://yixinglu.gitlab.io/enable_if.html

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

  1. template <bool, typename T=void>
  2. struct enable_if {
  3. };
  4.  
  5. template <typename T>
  6. struct enable_if<true, T> {
  7. using type = T;
  8. };

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

用法一:类型偏特化

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

  1. template <typename T, typename Enable=void>
  2. struct check;
  3.  
  4. template <typename T>
  5. struct check<T, typename std::enable_if<T::value>::type> {
  6. static constexpr bool value = T::value;
  7. };

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

用法二:控制函数返回类型

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

  1. template <std::size_t k, class T, class... Ts>
  2. typename std::enable_if<k==, typename element_type_holder<, T, Ts...>::type&>::type
  3. get(tuple<T, Ts...> &t) {
  4. return t.tail;
  5. }
  6.  
  7. template <std::size_t k, class T, class... Ts>
  8. typename std::enable_if<k!=, typename element_type_holder<k, T, Ts...>::type&>::type
  9. get(tuple<T, Ts...> &t) {
  10. tuple<Ts...> &base = t;
  11. return get<k->(base);
  12. }

由于函数模板不能偏特化,通过 enable_if 便可以根据 k 值的不同情况选择调用哪个 get,进而实现函数模板的多态。

用法三:校验函数模板参数类型

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

  1. template <typename T>
  2. typename std::enable_if<std::is_integral<T>::value, bool>::type
  3. is_odd(T t) {
  4. return bool(t%);
  5. }
  6.  
  7. template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
  8. bool is_even(T t) {
  9. return !is_odd(t);
  10. }

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

(转载)std::enable_if 的几种用法 c++11的更多相关文章

  1. 【转载】java final 关键字的几种用法

    原文链接点这里,感谢博主分享 在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构 ...

  2. 【转载】java static 关键字的四种用法

    原文链接点这里,感谢博主分享 在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构 ...

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

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

  4. Linux下dmesg命令处理故障和收集系统信息的7种用法

    目录: <syslog之一:Linux syslog日志系统详解> <syslog之二:syslog协议及rsyslog服务全解析> <syslog之三:建立Window ...

  5. c++中for的四种用法

    #include <algorithm> #include <vector> #include <iostream> using namespace std; in ...

  6. C++学习---- virtual的三种用法

    virtual用法一:多态 #include<iostream> using namespace std; class A{ public: virtual void display(){ ...

  7. virtual 三种用法

    virtual用法一 #include using namespace std;class A{public:     virtual  void  display(){  cout<<& ...

  8. javascript中this的四种用法

    javascript中this的四种用法 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2015-05-11我要评论 在javascript当中每一个function都是一个对象,所 ...

  9. using 的三种用法

    using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...

随机推荐

  1. postman~界面介绍

    本文摘抄自https://www.jianshu.com/p/b8b02afa74b1 官方文档:https://learning.getpostman.com/docs/postman/launch ...

  2. 一分钟玩转 Spring IoC!

    前言 「上一篇文章」我们对 Spring 有了初步的认识,而 Spring 全家桶中几乎所有组件都是依赖于 IoC 的. 刚开始听到 IoC,会觉得特别高大上,但其实掰开了很简单. 跟着我的脚步,一文 ...

  3. PHP timezone_location_get() 函数

    ------------恢复内容开始------------ 实例 返回指定时区的位置信息: <?php$tz=timezone_open("Asia/Taipei");ec ...

  4. MediaDevices.getUserMedia()

    MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道.此流可以包含一个视频轨道(来自硬件或 ...

  5. 5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制

    LINK:小V的序列 考试的时候 没想到正解 于是自闭. 题意很简单 就是 给出一个序列a 每次询问一个x 问序列中是否存在y 使得x^y的二进制位位1的个数<=3. 容易想到 暴力枚举. 第一 ...

  6. bzoj 2780 [Spoj]8093 Sevenk Love Oimaster

    LINK:Sevenk Love Oimaster 询问一个模式串在多少个文本串中出现过. 考虑广义SAM 统计这种数量问题一般有三种做法. 一种 暴力bitset 这道题可能可以过? 一种 暴力跳p ...

  7. PHP代码混淆与加密——php screw plus

    php是一个开源的.广受欢迎的语言,php应用常常是以代码明文的发式发布,但是有时候对于发布的代码我们想要进行保护,需要对php代码进行混淆与加密,让增加破解者的逆向难度,从而达到保护自己成果的目的. ...

  8. .NetCore 配合 Gitlab CI&CD 实践 - 开篇

    引言 这是一个系列的文章,讲述的是一个中小型开发团队如何从零开始使用搭建基建 GitLab 代码托管平台,以及使用 GitLab Runner 实现 CI/CD 的故事.本系列通过部署一个完整的 .n ...

  9. Android BottomNavigationView的用法

    BottomNavigationView是相当于一个导航的标签,但是它的形式就是像QQ,微信之类的界面 这三个图标就是BottomNavigationView的体现. 至于写出后怎样绑定这三个界面,就 ...

  10. Hexo博客部署到远程仓库(Conding、Gitee、Github)

    一.本地环境搭建 1.安装Git Git可以有效.高速的处理各种项目版本管理.也就是用来管理你的hexo博客文章,上传到GitHub的工具. Git下载地址 安装好了之后使用git -version查 ...