zoukankan      html  css  js  c++  java
  • (转载)std::enable_if 的几种用法 c++11

    今天看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==0, typename element_type_holder<0, 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!=0, typename element_type_holder<k, T, Ts...>::type&>::type
     9 get(tuple<T, Ts...> &t) {
    10   tuple<Ts...> &base = t;
    11   return get<k-1>(base); 
    12 }

    由于函数模板不能偏特化,通过 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); 
    }

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

  • 相关阅读:
    安装tomcat8过程记录
    epoll监听多文件描述符时调度顺序研究
    线程间通信之eventfd
    webstorm常用快捷键
    修改linux镜像源的方法
    如何使用《UNIX 网络编程》一书中的源码
    SSL的作用与目前主流的使用场景介绍
    SSL相关知识点架构整理
    SSL的发展历史
    实验室项目debug汇总
  • 原文地址:https://www.cnblogs.com/cutelife/p/11718614.html
Copyright © 2011-2022 走看看