Boost中Core模块的enable_if用法及说明

本文深入解析Boost库中enable_if,lazy_enable_if,disable_if,lazy_disable_if的作用与使用方法,通过实例展示了如何利用这些特性进行模板元编程,实现类型检查与错误处理。

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

头文件

boost/utility/enable_if.hpp

作用

enable_if,lazy_enable_if,disable_if,lazy_disable_if 作用说明

enable_if 说明

template <class Cond, class T = void>
 struct enable_if : public enable_if_c<Cond::value, T> {};

当Cond::value为真,enable_if,才会有类型type,且type为 T类型。

lazy_enable_if 说明

template <class Cond, class T> 
  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};

当Cond::value为真,lazy_enable_if,才会有类型T::type,常常与boost其他模块搭配使用。

disable_if 说明

template <class Cond, class T = void> 
  struct disable_if : public disable_if_c<Cond::value, T> {};

当Cond::value为假,disable_if,才会有类型type,且type为 T类型。

lazy_disable_if  说明

template <class Cond, class T> 
  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};

当Cond::value为假,lazy_disable_if,才会有类型T::type,常常与boost其他模块搭配使用。

enable_if,lazy_enable_if,disable_if,lazy_disable_if ,从本质上说,都是为了将不符合要求的参数剔除,传递了不符合要求的参数,在编译期间会报错。常常用于 模板类或模板函数的型参 类型,或者是 返回值 类型。

举例

enable_if,disable_if模板类 构造函数 型参

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/detail/lightweight_test.hpp>

using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;

struct container {
  bool my_value;

  template <class T>
  container(const T&, const typename enable_if<is_arithmetic<T>, T>::type * = 0):
  my_value(true) {}

  template <class T>
  container(const T&, const typename disable_if<is_arithmetic<T>, T>::type * = 0):
  my_value(false) {}
};

// example from Howard Hinnant (tests enable_if template members of a templated class)
template <class charT>
struct xstring
{
  template <class It>
  xstring(It begin, It end, typename 
          disable_if<is_arithmetic<It> >::type* = 0)
    : data(end-begin) {}
  
  int data;
};


int main()
{
 
  BOOST_TEST(container(1).my_value);
  BOOST_TEST(container(1.0).my_value);

  BOOST_TEST(!container("1").my_value);  
  BOOST_TEST(!container(static_cast<void*>(0)).my_value);  

  char sa[] = "123456";
  BOOST_TEST(xstring<char>(sa, sa+6).data == 6);


  return boost::report_errors();
}

enable_if,disable_if模板函数 返回值

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/detail/lightweight_test.hpp>

using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;

template <int N> struct dummy {
  dummy(int) {};
};

template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<0> = 0) { return true; }

template<class T>
typename disable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<1> = 0) { return false; }


int main()
{
 
  BOOST_TEST(arithmetic_object(1));
  BOOST_TEST(arithmetic_object(1.0));

  BOOST_TEST(!arithmetic_object("1"));  
  BOOST_TEST(!arithmetic_object(static_cast<void*>(0)));  

  return boost::report_errors();
}

lazy_enable_if

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/lightweight_test.hpp>

using boost::lazy_enable_if;
using boost::lazy_disable_if;

using boost::lazy_enable_if_c;
using boost::lazy_disable_if_c;


template <class T>
struct is_int_or_double {
  BOOST_STATIC_CONSTANT(bool, 
    value = (boost::is_same<T, int>::value || 
             boost::is_same<T, double>::value));
};

template <class T>
struct some_traits {
  typedef typename T::does_not_exist type;
};

template <>
struct some_traits<int> {
  typedef bool type;
};

template <>
struct some_traits<double> {
  typedef bool type;
};

template <class T>
struct make_bool {
  typedef bool type;
};

template <>
struct make_bool<int> {};

template <>
struct make_bool<double> {};

namespace A {

  template<class T>
  typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type
  foo(T t) { return true; }

  template<class T>
  typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type
  foo2(T t) { return true; }
}

namespace B {
  template<class T>
  typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type
  foo(T t) { return false; }

  template<class T>
  typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type
  foo2(T t) { return false; }
}

int main()
{
  using namespace A;
  using namespace B;
  BOOST_TEST(foo(1));
  BOOST_TEST(foo(1.0));

  BOOST_TEST(!foo("1"));  
  BOOST_TEST(!foo(static_cast<void*>(0)));  

  BOOST_TEST(foo2(1));
  BOOST_TEST(foo2(1.0));

  BOOST_TEST(!foo2("1"));  
  BOOST_TEST(!foo2(static_cast<void*>(0)));  

  return boost::report_errors();
}

源码

namespace boost
{
  template<typename T, typename R=void>
  struct enable_if_has_type
  {
    typedef R type;
  };
 
  template <bool B, class T = void>
  struct enable_if_c {
    typedef T type;
  };

  template <class T>
  struct enable_if_c<false, T> {};

  template <class Cond, class T = void> 
  struct enable_if : public enable_if_c<Cond::value, T> {};

  template <bool B, class T>
  struct lazy_enable_if_c {
    typedef typename T::type type;
  };

  template <class T>
  struct lazy_enable_if_c<false, T> {};

  template <class Cond, class T> 
  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};


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

  template <class T>
  struct disable_if_c<true, T> {};

  template <class Cond, class T = void> 
  struct disable_if : public disable_if_c<Cond::value, T> {};

  template <bool B, class T>
  struct lazy_disable_if_c {
    typedef typename T::type type;
  };

  template <class T>
  struct lazy_disable_if_c<true, T> {};

  template <class Cond, class T> 
  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};

} // namespace boost

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值