c ++从函数指针中提取参数类型列表

c++ Extract parameter type list from function pointer

我正在尝试从函数指针获取参数类型

这应该是工作最终产品

std::function<void(TestAppObject*, MemberFuncArgs<decltype(&TestAppObject::TestMethod)>::InputArgs)> func = &TestAppObject::TestMethod;

当前 MemberFuncArgs class

template<typename T>
struct MemberFuncArgs;

template<typename RT, typename Owner, typename ...Args>
struct MemberFuncArgs<RT(Owner::*)(Args...)>
{
    static const size_t ArgCount = sizeof...(Args);
    typedef RT ReturnType;
    typedef Args InputArgs;
};

编译器抛出错误 'Args': parameter pack must be expanded in this context

我只需要一种从函数指针中提取 Args... 类型的方法,这可能只是一个语法问题,我太笨了,看不出来...

编译器说你不能定义单一类型InputArgs

typedef Args InputArgs;

假定 Args 是可变参数列表。

也许你可以定义一个基于元组的类型

using InArgsTuple = std::tuple<Args...>;

因此您可以使用 std::tuple_element

Args... 中提取单个类型

所以,用一个小模板 meta-programming,你应该可以写一些东西

using TplT = MemberFuncArgs<decltype(&TestAppObject::TestMethod)>::InArgsTuple;

std::function<void(TestAppObject*, typename std::tuple_element<Is, TplT>::type ...)>
   func = &TestAppObject::TestMethod;

假设 Is... 是模板整数值的可变序列,从零到 sizeof...(Args)-1

下面是一个完整的编译C++20的例子

#include <tuple>
#include <functional>

struct TestAppObject
{
  int TestMethod (char, short, int, long, long long)
  { return 0; }
};

template <typename T>
struct MemberFuncArgs;

template <typename RT, typename Owner, typename ... Args>
struct MemberFuncArgs<RT(Owner::*)(Args...)>
{
  static constexpr std::size_t ArgCount = sizeof...(Args);

  using ReturnType  = RT;
  using InArgsTuple = std::tuple<Args...>;
};
    
int main()
{
  using MFA  = MemberFuncArgs<decltype(&TestAppObject::TestMethod)>;
  using FunT = decltype([]<std::size_t ... Is>(std::index_sequence<Is...>)
     -> std::function<void(TestAppObject*,
           typename std::tuple_element<Is, MFA::InArgsTuple>::type ...)>
     { return {}; }
     (std::make_index_sequence<MFA::ArgCount>{}));

  FunT  func = &TestAppObject::TestMethod;
}

如果你不能使用 C++20(所以没有模板 lambda 并且在未计算的上下文中没有 lambda)你可以用传统的模板函数替换 lambda,只声明(因为只在内部使用 decltype().

以下是完整编译C++14/C++17的例子。 #包括 #include

struct TestAppObject
{
  int TestMethod (char, short, int, long, long long)
  { return 0; }
};

template <typename T>
struct MemberFuncArgs;

template <typename RT, typename Owner, typename ... Args>
struct MemberFuncArgs<RT(Owner::*)(Args...)>
{
  static constexpr std::size_t ArgCount = sizeof...(Args);

  using ReturnType  = RT;
  using InArgsTuple = std::tuple<Args...>;
};

template <typename MFA, std::size_t ... Is>
std::function<void(TestAppObject*,
   typename std::tuple_element<Is, typename MFA::InArgsTuple>::type ...)>
      extra_function (std::index_sequence<Is...>);

int main()
{
  using MFA  = MemberFuncArgs<decltype(&TestAppObject::TestMethod)>;
  using FunT = decltype(extra_function<MFA>
                           (std::make_index_sequence<MFA::ArgCount>{}));

  FunT  func = &TestAppObject::TestMethod;
}