Convert type list with function at runtime

I have a list of types. I would like to create a tuple with the results of a function call for each type in this list, and then use this as arguments for another functor. So something like this:

template<typename F> struct function_traits; template<typename T, typename R, typename... Args> struct function_traits<R(T::*)(Args...) const> { using return_type = R; using param_types = std::tuple<Args...>; }; template<typename T> struct function_traits : public function_traits<decltype(&T::operator())> {}; template <typename T> T* get_arg(int id) { // Actual implementation omitted. Uses the id parameter to // do a lookup into a table and return an existing instance // of type T. return new T(); } template <typename Func> void call_func(Func&& func, int id) { using param_types = function_traits<Func>::param_types>; func(*get_arg<param_types>(id)...); // <--- Problem is this line } call_func([](int& a, char& b) { }, 3); 

The problem is that func(*get_arg<param_types>(id)...); actually does not compile, since param_types is a tuple, not a parameter package. The compiler generates this error: "there are no parameter packages available for extension." I would like this line to expand to:

 func(*get_arg<int>(id), *get_arg<char>(id)); 

And to have this work for any number of arguments. Is there any way to get this result?

This question seems similar, but it does not solve my problem: "unpacking" a tuple to call the pointer of the corresponding function . I have a list of types and I want to generate a list of values ​​to use as arguments to a function. If I had a list of values, I could expand them and call the function described in this question, but I do not.

+5
source share
1 answer

Not sure if this is what you need.

I don’t know how to deploy call_func() parameters package inside call_func() , but if you allow to use auxiliary structure and compiler with C ++ 14 ...

I prepared the following example with return type support.

 #include <tuple> template<typename F> struct function_traits; template<typename T, typename R, typename... Args> struct function_traits<R(T::*)(Args...) const> { using return_type = R; using param_types = std::tuple<Args...>; }; template<typename T> struct function_traits : public function_traits<decltype(&T::operator())> {}; template <typename T, typename ... Args> T get_arg (std::tuple<Args...> const & tpl) { return std::get<typename std::decay<T>::type>(tpl); } template <typename ...> struct call_func_helper; template <typename Func, typename Ret, typename ... Args> struct call_func_helper<Func, Ret, std::tuple<Args...>> { template <typename T, typename R = Ret> static typename std::enable_if<false == std::is_same<void, R>::value, R>::type fn (Func const & func, T const & t) { return func(get_arg<Args>(t)...); } template <typename T, typename R = Ret> static typename std::enable_if<true == std::is_same<void, R>::value, R>::type fn (Func const & func, T const & t) { func(get_arg<Args>(t)...); } }; template <typename Func, typename T, typename R = typename function_traits<Func>::return_type> R call_func (Func const & func, T const & id) { using param_types = typename function_traits<Func>::param_types; return call_func_helper<Func, R, param_types>::fn(func, id); } int main() { call_func([](int const & a, char const & b) { }, std::make_tuple(3, '6')); return 0; } 

Hope this helps.

+1
source

All Articles