2011-12-21 49 views
3

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

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 Doption的某些部分。

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> - 检查-i选项是否存在于结构的方式。 当然SFINAE适用于函数名称或函数签名,但不确定 它适用于枚举值。

+0

请注意,我们取消了这个问题,因为我刚写完我的答案,当你删除它。 :) – Xeo 2011-12-21 22:57:06

+0

你希望完成什么? – 2011-12-22 00:10:40

回答

6

如果你可以使用C++ 11,这完全是微不足道的:

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版本是(奇怪)相似:

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 
} 
+0

我删除了,因为我发现这个问题已被其他帖子回答。尽管如此,C++ 11的答案看起来不错。 – xosp7tom 2011-12-22 23:15:55