是否可以从模板< auto MEMFN>中提取参数类型? [英] Is it possible to extract parameter types from a template <auto MEMFN>?

查看:67
本文介绍了是否可以从模板< auto MEMFN>中提取参数类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以创建一个具有模板参数 auto MEMFN (成员函数指针)的独立模板函数,并且具有与MEMFN相同的返回和参数类型?

Is it possible to create a standalone template function which has a template parameter auto MEMFN (a member function pointer), and has the same return and parameter types as MEMFN has?

因此,如果MEMFN的类型为

So, if MEMFN's type is

RETURN (OBJECT::*)(PARAMETERS...)

然后所需的功能是这样的:

then the desired function is this:

template <auto MEMFN>
RETURN foo(OBJECT &, PARAMETERS...);

我的问题是如何提取 PARAMETERS ... MEMFN类型的c> 返回对象很容易

My problem is how to extract PARAMETERS... from MEMFN's type (RETURN and OBJECT are easy to do).

所以我可以这样调用该函数:

So I can call this function like this:

Object o;
foo<&Object::func>(o, <parameters>...);






根据nm的要求,以下是实际代码的示例:


As for request from n.m., here is a stripped down example from an actual code:

#include <utility>

template <typename RETURN, typename OBJECT, typename ...PARAMETERS>
struct Wrapper {
    template <RETURN (OBJECT::*MEMFN)(PARAMETERS...)>
    RETURN foo(PARAMETERS... parameters) {
        // do whatever with MEMFN, parameters, etc. here, not part of the problem
    }
};

struct Object {
    template <auto MEMFN, typename RETURN, typename OBJECT, typename ...PARAMETERS>
    RETURN call(OBJECT &&object, PARAMETERS &&...parameters) {
        // here, MEMFN parameters and PARAMETERS must be the same

        // Wrapper actually not created here, it is accessed by other means
        Wrapper<RETURN, typename std::decay<OBJECT>::type, PARAMETERS...> w;

        return w.template foo<MEMFN>(std::forward<PARAMETERS>(parameters)...);
    }
};

struct Foo {
    void fn(int);
};

int main() {
    Object o;
    Foo f;
    o.call<&Foo::fn, void, Foo &, int>(f, 42);

    // this is wanted instead:
    // o.call<&Foo::fn>(f, 42);
}


推荐答案

如果您放松对独立运行时,您可以执行以下操作:

If you relax your demand on being standalone you can do something like:

#include <iostream>

template <auto MEMFN, class = decltype(MEMFN)>
struct S;

template <auto MEMFN, class Ret, class T, class... Args>
struct S<MEMFN, Ret (T::*)(Args...)> {
    static Ret foo(T &o, Args... args) {
        (o.*MEMFN)(args...);
    }
};

struct A {
    void foo(int a, int b) {
        std::cout << a << " " << b << std::endl;
    }
};

int main() {
    A a;
    S<&A::foo>::foo(a, 1, 2);
}

[实时演示]

如果没有,那么您将不得不拥有耐心地为每个可能数量的参数创建函数重载:

If no then you gonna have to have a patience to create a function overloads for each possible number of parameters:

#include <type_traits>
#include <tuple>
#include <iostream>

template <class, std::size_t>
struct DeduceParam;

template <class Ret, class T, class... Args, std::size_t N>
struct DeduceParam<Ret (T::*)(Args...), N> {
    using type = std::tuple_element_t<N, std::tuple<Args...>>;
};

template <class>
struct DeduceResultAndType;

template <class Ret, class T, class... Args>
struct DeduceResultAndType<Ret (T::*)(Args...)> {
    using result = Ret;
    using type = T;
    static constexpr decltype(sizeof(T)) size = sizeof...(Args);
};

template <auto MEMFN, class DRAT = DeduceResultAndType<decltype(MEMFN)>, std::enable_if_t<DRAT::size == 1>* = nullptr>
typename DRAT::result  foo(typename DRAT::type o, typename DeduceParam<decltype(MEMFN), 0>::type param1) {
}

template <auto MEMFN, class DRAT = DeduceResultAndType<decltype(MEMFN)>, std::enable_if_t<DRAT::size == 2>* = nullptr>
typename DRAT::result  foo(typename DRAT::type o, typename DeduceParam<decltype(MEMFN), 0>::type param1, 
                                                  typename DeduceParam<decltype(MEMFN), 1>::type param2) {
}

struct A {
    void foo(int a, int b) {
        std::cout << a << " " << b << std::endl;
    }
};

int main() {
    A a;
    foo<&A::foo>(a, 1, 2);
}

这篇关于是否可以从模板&lt; auto MEMFN&gt;中提取参数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆