繁体   English   中英

在运行时使用功能转换类型列表

[英]Transform typelist with function at runtime

我有一个类型列表。 我想创建一个元组,其结果是对该列表中的每种类型调用一个函数,然后将其用作另一个函子的参数。 所以像这样:

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

问题是func(*get_arg<param_types>(id)...); 实际上不会编译,因为param_types是一个元组而不是参数包。 编译器会产生以下错误:“没有可用的参数包进行扩展”。 我希望发生的事情是将该行扩展为:

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

并使其适用于任何数量的参数。 有什么办法可以得到那个结果?

这个问题似乎很相似,但不能单独解决我的问题: “拆包”元组以调用匹配的函数指针 我有一个类型列表,从中我想生成一个值列表用作函数参数。 如果我有值列表,则可以扩展它们并调用该问题中概述的函数,但我没有。

不知道那是你想要什么。

我不知道如何扩大,内部call_func()参数包params_type但是,如果你买得起使用辅助结构,并用C ++ 14的编译器...

我准备了下面的示例,其中支持返回类型。

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

希望这可以帮助。

暂无
暂无

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

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