C++11 - template std::enable_if and std::result_of

C++11 - template std::enable_if and std::result_of

本文关键字:std of and result if enable template C++11      更新时间:2023-10-16

我已经创建了这个专门用于void/非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++模板参数作为函数调用名)

然而,这给了我一堆错误(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的void/non-void结果"创建"专门化函数?

在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返回类型使用箭头语法,这看起来只是更干净的我。另外,既然你已经有了MethodType类型,为什么还要在MethodName上使用decltype呢?同样,result_of在访问类型之前需要typename。

如上所述,虽然没有可能的使用,但我不确定这是否是您所追求的。

注意:std::enable_if_t在c++ 14中是可用的,如果你不能使用typename std::enable_if<...>::type来代替。

你正好错过了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;

去掉第一个模板参数。