有没有办法使用替换失败不是枚举错误(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 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适用于功能名称或功能签名,但不确定
它适用于枚举值。
答案 0 :(得分: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
}