跟我学C++编程中级篇——std::enable_if的使用

本文详细介绍了std::enable_if在C++模板元编程中的作用,包括模板偏特化、控制函数返回值和类型限定。同时讨论了C++20引入的Concepts替代方案,并通过实例展示了std::enable_if的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、std::enable_if介绍

对于SFINAE(不清楚的可以翻一下以前的相关文章)开发者来说,std::enable_if是绕不开的一个小话题。在C++11至C++20间,其在模板的元编程中起到了重要的作用。不过在C++20后Cocepts可以实现更清晰更简单的方式。它的定义方式为:

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

从C++14起还提供了一个辅助的类型,用来更简单的元编程中使用:

template< bool B, class T = void >
using enable_if_t = typename enable_if<B,T>::type;

其实非常好理解,这个模板结构体的第一个参数是bool型,第二个默认是个void,就是说,第一个参数决定了是否启用第二个参数。其具体的实现可能为:

template<bool B, class T = void>
struct enable_if {
   
   };
 
template<class T>
struct enable_if<true, T> {
   
    typedef T type; };

这下就明白了吧。
需要注意的是,它的使用错误的情况:

 
struct T {
   
   
    enum {
   
    int_t,float_t } m_type;
    template <typename Integer,
              typename = std::enable_if_t<std::is_integral_v<Integer>>
    >
    T(Integer) : m_type(int_t) {
   
   }
 
    template <typename Floating,
              typename = std::enable_if_t<std::is_floating_point_v<Floating>>
    >
    T(Floating) : m_type(float_t) {
   
   } // 错误:无法被重载
};

正确的应该是:

#include <iostream>

using namespace std;
struct T {
   
   
  enum {
   
    int_t, float_t } m_type;
  template <typename Integer, std::enable_if_t<std::is_integral_v<Integer>, int> = 0> T(Integer) : m_type(int_t) {
   
   }

  template <typename Floating, std::enable_if_t<std::is_floating_point_v<Floating>, int> = 0>
  T(Floating) : m_type(float_t) {
   
   } // OK
};
int main() {
   
   
  int d = 0;
  float dd = 0.0f;
  T t(d);
  T tt(dd);
  
  return 0;
}

//其编译后为:
#include <iostream>
using namespace std;
struct T
{
   
   
  enum 
  {
   
   
    int_t, 
    float_t
  };
  
  enum (unnamed) m_type;
  template<typename Integer, std::enable_if_t<std::is_integral_v<Integer>, int>  = 0>
  inline T(Integer)
  : m_type{
   
   int_t}
  {
   
   
  }
  
  /* First instantiated from: insights.cpp:15 */
  #ifdef INSIGHTS_USE_TEMPLATE
  template<>
  inline T<int, 0>(int)
  : m_type{
   
   int_t}
  {
   
   
  }
  #endif 
  
  template<typename Floating, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值