Reputation: 3356
struct substitute_failure{};
template<typename T>
struct substitute_success:true_type{};
template<>
struct substitute_success<substitute_failure>:false_type{};
template<typename T>
class get_result;
template<typename T>
struct has_f:substitute_success<typename get_result<T>::type>{};
template<typename T>
class get_result{
template<typename X>
static auto check(X const& x)->decltype(f(x));
static substitute_failure check(...);
public:
using type = decltype(check(declval<T>()));
};
template<typename T>
constexpr bool Has_f(){
return has_f<T>::value;
}
template<bool B,typename T=void>
struct enable_if1{
typedef T type;
};
template<typename T>
struct enable_if1<false,T>{};
template<bool B,typename T=void>
using Enable_if = typename enable_if1<B,T>::type; //Error: no type named 'type' in 'struct enable_if1<false, void>'
class myFun{
public:
void f(){cout << "have fun!\n";}
};
int main(){
myFun mf{};
Enable_if<Has_f<myFun>()> mf.f(); //Error: expected initializer before '.' token
return 0;
}
I got errors(also addressed in the code as annotations):
Error: no type named 'type' in 'struct enable_if1'
Error: expected initializer before '.' token
According to SFINAE, the compiler should just neglect the "failed case", right? I also tried std::enable_if
and got the same errors.
Upvotes: 0
Views: 87
Reputation: 62563
You do not seem to understand how SFINAE works. It is not a magic wand to ignore malformed code. SFINAE only works for functions or class declarations, and only in a sense that a failing function definition or class declaration will not be considered. In your particular case, you are unconditionally definining enable_if
as a template alias to enable_if1::type
, so if you are creating a variable of this type (as you seem to try to do), you have to have this type defined.
However, it is hard to tell what exactly are you trying to do, since your code is not syntaxically correct in any way.
Upvotes: 1