• C++11模板元编程-std::enable_if示例详解


    传送门 ==>> AutoSAR实战系列300讲「糖果Autosar」总目录

    C++11中引入了std::enable_if函数,函数原型如下:

    template< bool B, class T = void >
    struct enable_if;
    
    • 1
    • 2

    可能的函数实现:

    template<bool B, class T = void>
    struct enable_if {};
      
    template<class T>
    struct enable_if<true, T> { typedef T type; };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    由上可知,只有当第一个模板参数为true时,enable_if会包含一个type=T的公有成员,否则没有该公有成员。

    头文件:

    #include 
    
    • 1

    std::enable_if使用场景

    1 限制模板函数的参数类型

    在某些场景下,我们需要实现只有特定类型可以调用的模板函数。如下代码所示,通过对返回值使用std::enable_if和在模板参数中使用std::enable_if均实现了只允许整形参数调用函数的功能。

    // enable_if example: two ways of using enable_if
    #include 
    #include 
     
    // 1. the return type (bool) is only valid if T is an integral type:
    template <class T>
    typename std::enable_if<std::is_integral<T>::value,bool>::type
     is_odd (T i) {return bool(i%2);}
     
    // 2. the second template argument is only valid if T is an integral type:
    template < class T,class = typename std::enable_if<std::is_integral<T>::value>::type>
    bool is_even (T i) {return !bool(i%2);}
     
    int main() {
     
     short int i = 1;  // code does not compile if type of i is not integral
     
     std::cout << std::boolalpha;
     std::cout << "i is odd: " << is_odd(i) << std::endl;
     std::cout << "i is even: " << is_even(i) << std::endl;
     
     return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    当使用float类型参数调用函数时,程序会报错:

    error: no matching function for call to ‘is_odd(float&)’

    2 模板类型偏特化

    在使用模板编程时,可以利用std::enable_if的特性根据模板参数的不同特性进行不同的类型选择。

    如下所示,我们可以实现一个检测变量是否为智能指针的实现:

    #include 
    #include 
    #include 
     
    template <typename T>
    struct is_smart_pointer_helper : public std::false_type {};
     
    template <typename T>
    struct is_smart_pointer_helper<std::shared_ptr<T> > : public std::true_type {};
     
    template <typename T>
    struct is_smart_pointer_helper<std::unique_ptr<T> > : public std::true_type {};
     
    template <typename T>
    struct is_smart_pointer_helper<std::weak_ptr<T> > : public std::true_type {};
     
    template <typename T>
    struct is_smart_pointer 
    : public is_smart_pointer_helper<typename std::remove_cv<T>::type> 
    {
    };
     
    template <typename T>
    typename std::enable_if<is_smart_pointer<T>::value,void>::type 
    check_smart_pointer(const T& t)
    {
      std::cout << "is smart pointer" << std::endl;
    }
     
    template <typename T>
    typename std::enable_if<!is_smart_pointer<T>::value,void>::type 
    check_smart_pointer(const T& t)
    {
      std::cout << "not smart pointer" << std::endl;
    }
     
    int main()
    {
      int* p(new int(2));
      std::shared_ptr<int> pp(new int(2));
      std::unique_ptr<int> upp(new int(4));
     
      check_smart_pointer(p);
      check_smart_pointer(pp);
      check_smart_pointer(upp);
       
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    程序输出:

    not smart pointer
    is smart pointer
    is smart pointer
    
    • 1
    • 2
    • 3
  • 相关阅读:
    笔训day1
    【cookie和session】娓娓道来cookie和session
    Java的日期与时间之如何计算业务代码的运行时间呢?
    接口开发不用写Controller、Service、Dao、Mapper、XML、VO,全自动生成!
    右旋酮洛芬-β-环糊精微球|聚苹果酸-羟喜树碱前药(PMLA-HCPT)|Gd2O3/CuS复合白蛋白纳米粒(科研级)
    阿曼市场最全开发攻略,看这一篇就够了
    Linux进程管理和计划任务与系统备份恢复
    Selenium Web自动化测试 —— 高级控件交互方法!
    java代码审计-SSRF
    flutter开发实战-防抖Debounce与节流Throttler实现
  • 原文地址:https://blog.csdn.net/huihuige092/article/details/126308300