我创建了这个来专门化void / non-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()
{
//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
结果。
是否可以&#34;创建&#34;具有MethodName
答案 0 :(得分: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
。
答案 1 :(得分: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;