簡體   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