Replacement error is not an error (SFINAE) for listing

Is there a way to use replacement failure - is this not an error (SFINAE) for enumeration?

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 provide default behavior when iOption does not exist. Therefore, I separate the Do DoOption part.

 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 part of DoesOptionExist<T> is the way to check if iOption exists in the structure. Of course, SFINAE works for a function name or function signature, but I'm not sure it works for an enumeration value.

+3
source share
1 answer

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 (surprisingly) is 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); }; 

Using:

 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 } 
+6
source

All Articles