如何编写用于选择函数的样板代码

时间:2016-02-11 21:55:29

标签: c++ template-meta-programming

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;
}

我收到错误(在代码中也作为注释解决):

错误:'struct enable_if1'

中没有名为'type'的类型

错误:'。'之前的预期初始化程序。令牌

根据SFINAE,编译器应该忽略“失败的案例”,对吧?我也试过std::enable_if并得到了同样的错误。

1 个答案:

答案 0 :(得分:1)

您似乎不了解SFINAE的工作原理。忽略格式错误的代码并不是一根魔杖。 SFINAE仅适用于函数或类声明,并且仅在某种意义上不考虑失败的函数定义或类声明。在您的特定情况下,您无条件地将enable_if定义为enable_if1::type的模板别名,因此如果您要创建此类型的变量(您似乎尝试这样做),则必须拥有此类型定义。

但是,很难说你究竟想要做什么,因为你的代码在语法上并不是正确的。