Milo Lu
Milo Lu

Reputation: 3356

How to write the boilerplate code for selecting functions

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

Answers (1)

SergeyA
SergeyA

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

Related Questions