Substitution failure is not an error (SFINAE) for enum
c++, sfinae, traits
Solution
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);
};
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);
};
Usage:
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
}
Problem
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 }; ``` 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> >(); }; ``` 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.