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;
}
我正在尝试从函数指针获取参数类型
这应该是工作最终产品
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;
}