2016-10-17 61 views
0

我创造了这个专门模板空/非空方法C++ 11 - 模板的std :: enable_if和std ::的result_of

template <typename ClassType, 
     typename MethodType, MethodType MethodName,   
     typename std::enable_if <std::is_same<void, std::result_of<decltype(MethodName)(ClassType)>::type>::value> ::type* = nullptr 
> 
static int function() 
{ 
    //void 
    //.... 
} 



template <typename ClassType, 
     typename MethodType, MethodType MethodName,   
     typename std::enable_if <!std::is_same<void, std::result_of<decltype(MethodName)(ClassType)>::type>::value> ::type* = nullptr 
> 
static int function() 
{ 
    //non-void 
    //.... 
} 

//And I want to call it like this 
function<Foo, void (Foo::*)(void), &Foo::Print>(); 
function<Foo, int (Foo::*)(void), &Foo::Print2>(); 

(基于这样的回答:C++ template parameter as function call name

Hovewer,这给我一堆错误(MSVC 2015)。如果我在

内运行
template <typename ClassType, 
     typename MethodType, MethodType MethodName  
> 
static int print() 
{ 
    std::cout << "C: " << std::is_same<void, std::result_of<decltype(MethodName)(ClassType)>::type>::value << std::endl; 
} 

我得到true结果。

是否有可能“专业化”创建功能为MethodName的无效/非空效果?

+0

就像idenote,如果你想检查无效只是使用is_void,它比__same

+0

@AdrianLis我知道,我也试过,但也有同样的结果(加上在某些情况下,我不想测试无效,这是只是为了简化示例;-)) –

+2

你还没有发布你得到的错误,但我可以看到你在'std :: result_of <...>' – MarekR

回答

1

您刚才错过typename

作为替代方案,我建议:

template <typename F, F f> struct function_helper; 

template <typename C, typename ... Ts, void (C::*m)(Ts...)> 
struct function_helper<void (C::*)(Ts...), m> 
{ 
    int operator()() const { /* void implementation*/ } 
}; 

template <typename C, typename Ret, typename ... Ts, void (C::*m)(Ts...)> 
struct function_helper<Ret (C::*)(Ts...), m> 
{ 
    int operator()() const { /* non-void implementation*/ } 
}; 

template <typename F, F f> 
static int function() 
{ 
    return function_helper<F, f>{}(); 
} 

随着使用

function<void (Foo::*)(), &Foo::Print>(); 
function<int (Foo::*)(), &Foo::Print2>(); 

function<decltype(&Foo::Print), &Foo::Print>(); 
function<decltype(&Foo::Print2), &Foo::Print2>(); 

用C++ 17中,我们可以摆脱第一个模板参数与template <auto f> struct function_helper;

2

这GCC

#include <iostream> 
#include <type_traits> 
using namespace std; 

template <typename ClassType, typename MethodType, MethodType MethodName> 
static auto function() 
    -> std::enable_if_t<std::is_void<typename std::result_of<MethodType(ClassType)>::type>::value, int> 
{ 
    //void 
    //.... 
} 

template <typename ClassType, typename MethodType, MethodType MethodName> 
static auto function() 
    -> std::enable_if_t<!std::is_void<typename std::result_of<MethodType(ClassType)>::type>::value, int> 
{ 
    //non-void 
    //.... 
} 

下编译好,我不知道这是你在照顾什么,但我感动enable_if使用箭头语法返回类型,这看起来只是更干净的给我。此外,为什么还要在MethodName上使用decltype,因为您已经有类型为MethodType。在访问该类型之前,result_of还需要typename。

这与上面的编译虽然没有可能的用法,我不知道这是你是什么后。

说明:std::enable_if_t在C++ 14中可用,如果您不能将该更改用于typename std::enable_if<...>::type,则可以使用该更改。

相关问题