繁体   English   中英

C ++函数重载,enable_if的替代方法?

[英]C++ function overloading, alternatives to enable_if?

如果有函数,请在模板化类中insert ,然后将其重载以采用填充模式:

void insert(const size_type N, const value_type &element);

或范围模式:

template <class iterator_type>
void insert(const iterator_type begin, const iterator_type end)

当我将类的value_type指定为int时,将导致以下调用:

insert(500, 50);

是模棱两可的,因为它假定500是一个int ,因此不匹配size_type N ,并且不调用填充模式函数,而是调用模板化范围函数,并且失败。

这是C ++ 03兼容的库,不能使用boost等外部库,只能使用内置的C ++代码。 我发现不需要C ++ 11的enable_if的唯一解决方法是创建其他重载,用intlong intchar等替换size_type ,并从它们调用fill函数。 显然这是有问题的,因为您可以有许多不同的类型匹配500 有什么建议么?

利用SFINAE:

void insert(const size_type N, const value_type &element);

template <class iterator_type>
void insert(iterator_type begin, iterator_type end, char (*)[sizeof(*begin)] = NULL);

insert范围版本中的额外哑元参数将由编译器优化。 它唯一的作用是消除模板函数的重载解析,以解决不能与取消引用运算符一起使用的类型。

技巧说明:

char (*)[sizeof(*begin)]表示一个指向大小等于sizeof(*begin)的char数组的指针。 如果变量begin无法取消引用,则将是一个错误。 但是,在函数重载解析期间考虑函数模板的情况下,此类错误不会停止编译,而只会丢弃模板(“替换失败不是错误-SFINAE”)。

根据您支持的确切编译器,无论如何,enable_if都可能是内置的,它存在于TR1中。

但是,enable_if的实现很简单。 您也可以直接从Boost复制它。 实际上,它太短了,我将在此答案中发布它。

namespace boost
{

  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

在Puppy的答案帮助下,它得以解决:

// Fill insert
void insert(const size_type N, const value_type &element);


// Enable_if template
template <bool condition, class T = void> 
struct enable_if_c
{
    typedef T type;
};

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


// Range insert:
template <class iterator_type>
iterator insert (const typename enable_if_c<!std::numeric_limits<iterator_type>::is_integer, iterator_type>::type &first, const iterator_type &last);

numeric_limits是C ++ 03安全的,并且在包括MSVC 2010在内的所有(经过测试)编译器中均可使用。此检查确保提供给range-insert的类型不是整数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM