简体   繁体   English

C ++ 11-模板std :: enable_if和std :: result_of

[英]C++11 - template std::enable_if and std::result_of

I have created this to specialize template for void / non-void methods 我创建了这个模板,专门用于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>();

(Based on this answer: C++ template parameter as function call name ) (基于此答案: C ++模板参数作为函数调用名称

Hovewer, this gives me bunch of errors (MSVC 2015). 专家,这给了我很多错误(MSVC 2015)。 If I run this inside of 如果我在里面运行

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

I got true result. 我得到了true结果。

Is it possible to "create" function with specialisation for void / non-void results of MethodName ? 是否有可能针对MethodName无效/非无效结果专门创建“创建”函数?

This compiles fine under GCC 这在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
   //....
}

I am not sure if this is what you are looking after but I moved enable_if to return type using the arrow syntax, this looks just more clean to me. 我不确定这是否是您要照顾的东西,但是我使用箭头语法将enable_if移回了类型,这对我来说看起来更加干净。 Also why bother using decltype on MethodName since you already have the type as MethodType. 还要为什么还要在MethodName上使用decltype,因为您已经拥有类型作为MethodType。 Also result_of needs typename before accessing the type. 同样,result_of需要在访问类型之前输入typename。

This as above does compile although without possible usage I am not sure if this is what you are after. 上面的代码确实可以编译,尽管没有可能的用法,我不确定这是否是您要的。

note: std::enable_if_t is avaialble in C++14 if you can't use that change to typename std::enable_if<...>::type instead. 注意: std::enable_if_t是C ++ 14 avaialble如果你不能使用变更typename std::enable_if<...>::type来代替。

You have just miss typename . 您只是想念typename

As alternative I suggest: 作为替代,我建议:

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>{}();
}

With usage 随着使用

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

or 要么

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

With C++17, we may get rid of first template argument with template <auto f> struct function_helper; 在C ++ 17中,我们可以使用template <auto f> struct function_helper;摆脱第一个模板参数template <auto f> struct function_helper;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM