替换失败不是枚举的错误(SFINAE) [英] Substitution failure is not an error (SFINAE) for enum

查看:193
本文介绍了替换失败不是枚举的错误(SFINAE)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法使用替换失败不是枚举的错误(SFINAE)

Is there a way to use Substitution failure is not an error (SFINAE) for enum?

template <typename T>
struct Traits
{
}
template <>
struct Traits<A>
{
};
template <>
struct Traits<B>
{
  enum
  {
     iOption = 1
  };
};

template <T>
void Do()
{
  // use Traits<T>::iOption
};

然后, Do< B>(); 工作, Do< A>(); 失败。但是,当iOption不存在时,我可以提供默认行为。
所以我将Do的一部分分离出来。

Then, Do<B>(); works and Do<A>(); fails. However, I can supply a default behavior when iOption does not exist. So I separate out some part of Do to DoOption.

template <typename T, bool bOptionExist>
void DoOption()
{
  // can't use Traits<T>::iOption. do some default behavior 
};
template <typename T>
void DoOption<T, true>()
{ 
  // use Traits<T>::iOption
};
template <T>
void Do()
{
  // 'Do' does not use Traits<T>::iOption. Such codes are delegated to DoOption.
  DoOption<T, DoesOptionExist<T> >();
};

现在,缺少的部分是 DoesOptionExist< T> - 一种检查结构体中是否存在iOption的方法。
当然,SFINAE用于函数名或函数签名,但不确定
它适用于枚举值。

Now, the missing piece is DoesOptionExist<T> - a way to check whether iOption exists in the struct. Certainly SFINAE works for function name or function signature, but not sure it works for enum value.

推荐答案

如果你可以使用C ++ 11,这是完全平凡的:

If you can use C++11, this is completely trivial:

template<class T>
struct has_nested_option{
  typedef char yes;
  typedef yes (&no)[2];

  template<class U>
  static yes test(decltype(U::option)*);
  template<class U>
  static no  test(...);

  static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};

C ++ 03版本是令人惊讶的类似:

The C++03 version is (surprisingly) similar:

template<class T>
struct has_nested_option{
  typedef char yes;
  typedef yes (&no)[2];

  template<int>
  struct test2;

  template<class U>
  static yes test(test2<U::option>*);
  template<class U>
  static no  test(...);

  static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};

用法:

struct foo{
  enum { option = 1 };
};

struct bar{};

#include <type_traits>

template<class T>
typename std::enable_if<
  has_nested_option<T>::value
>::type Do(){
}

int main(){
  Do<foo>();
  Do<bar>(); // error here, since you provided no other viable overload
}

这篇关于替换失败不是枚举的错误(SFINAE)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆