2016-10-17 81 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,則可以使用該更改。

相關問題