C++ 使用std::function作为参数的可变模板

C++ 使用std::function作为参数的可变模板,c++,c++11,templates,variadic-templates,std-function,C++,C++11,Templates,Variadic Templates,Std Function,如何简化下面的代码。这里可能使用元组吗?如果是,你能解释一下怎么做吗 template<typename Out, typename T1, typename T2, typename T3, typename T4> void ProcessIncomingCommand(PClientContext pClientContext, DWORD & bytesProcessed, const std::function<Out(T1, T2, T3,

如何简化下面的代码。这里可能使用元组吗?如果是,你能解释一下怎么做吗

template<typename Out, typename T1, typename T2, typename T3, typename T4>
void ProcessIncomingCommand(PClientContext pClientContext,
    DWORD & bytesProcessed,
    const std::function<Out(T1, T2, T3, T4)> &function,
    const std::vector<UINT> &params);

template<typename Out, typename T1, typename T2, typename T3>
static void ProcessIncomingCommand(PClientContext pClientContext,
    DWORD & bytesProcessed,
    const std::function<Out(T1, T2, T3)> &function,
    const std::vector<UINT> &params);

template<typename Out, typename T1, typename T2>
static void ProcessIncomingCommand(PClientContext pClientContext,
    DWORD & bytesProcessed,
    const std::function<Out(T1, T2)> &function,
    const std::vector<UINT> &params);
我如何在这里使用答案

template<typename Out, typename... T>static void ProcessIncomingCommand(PClientContext pClientContext,
DWORD & bytesProcessed,
const std::function<Out(T...)> &function,
const std::vector<UINT> &params)
templatestatic void ProcessIncomingCommand(PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量标准::向量和参数)
这是编译的

template<typename Out, typename... T>
static void ProcessIncomingCommand(PClientContext pClientContext,
    DWORD & bytesProcessed,
    const std::function<Out(T...)> &function,
    const T&... params) { function(params...); }

int main()
{
  PClientContext p;
  DWORD d = 0.5;
  std::function<int(double, int, char)> f;
  double a;
  int b;
  char c;
  ProcessIncomingCommand(p, d, f, a, b, c);
}
模板
静态void ProcessIncomingCommand(PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量T&…params){函数(params…;}
int main()
{
PClientContext p;
德沃德d=0.5;
std::函数f;
双a;
int b;
字符c;
进程输入命令(p、d、f、a、b、c);
}
如果您想将参数作为元组传递,那么它将变得更加棘手: 看见
当然,如果您更改
函数
以获取元组而不是参数列表…

不确定。。。但我想您需要一个函数助手和
std::index\u序列
(或类似的东西)

一个可能的例子

template <typename Out, typename ... Ts, std::size_t ... Is>
static Out PIC_helper (
   PClientContext pClientContext,
   DWORD & bytesProcessed,
   const std::function<Out(Ts...)> &function,
   const std::vector<UINT> &params,
   std::index_sequence<Is...> const &)
 { return function( static_cast<Ts>(params.at(Is))... ); }

template <typename Out, typename ... Ts>
static void ProcessIncomingCommand (
   PClientContext pClientContext,
   DWORD & bytesProcessed,
   const std::function<Out(Ts...)> &function,
   const std::vector<UINT> &params)
 {
   Out resFromFunction
      = PIC_helper(pClientContext, bytesProcessed, function, params,
                   std::make_index_sequence<sizeof...(Ts)>());

   // other ...
 }
模板
静态输出picu辅助程序(
PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量标准::向量和参数,
std::index_序列常量&)
{返回函数(static_cast(params.at(Is))…);}
模板
静态void ProcessIncomingCommand(
PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量标准::向量和参数)
{
Out resfrom函数
=PIC_helper(pClientContext、字节处理、函数、参数、,
std::make_index_sequence());
//其他。。。
}

观察到
std::index_sequence
std::make_index_sequence()
是C++14特性;但是,如果您需要一个C++11解决方案,您可以很容易地创建一些东西来替代它们。

看起来您需要这样的东西

template<typename ResultType, std::size_t... I>
ResultType tuple_from_vector_impl(std::vector<UINT> params, std::index_sequence<I...>)
{
    return std::make_tuple(static_cast<decltype(std::get<I>(std::declval<ResultType>()))>(params[I])...);
}

template<typename... Args, typename Indices = std::index_sequence_for<Args...>>
std::tuple<Args...> tuple_from_vector(std::vector<UINT> params)
{
    return tuple_from_vector_impl<std::tuple<Args...>>(params, Indices{});
}

template<typename Out, typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
                            DWORD & bytesProcessed,
                            const std::function<Out(Args...)> &function,
                            const std::vector<UINT> &params)
{
    // preamble
    std::tuple<Args...> args = tuple_from_vector<Args...>(params);
    Out result = std::apply(function, args);
    // postamble
}

template<typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
                            DWORD & bytesProcessed,
                            const std::function<void(Args...)> &function,
                            const std::vector<UINT> &params)
{
    // preamble
    std::tuple<Args...> args = tuple_from_vector<Args...>(params);
    std::apply(function, args);
    // postamble
}
模板
来自向量impl的结果类型元组(std::vector params,std::index\u序列)
{
返回std::make_tuple(static_cast(params[I])…);
}
模板
std::tuple tuple\u from_vector(std::vector params)
{
从向量impl返回元组(参数,索引{});
}
模板
void ProcessIncomingCommand(PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量标准::向量和参数)
{
//序言
std::tuple args=来自向量的tuple_(params);
输出结果=标准::应用(函数,参数);
//邮戳
}
模板
void ProcessIncomingCommand(PClientContext PClientContext,
德沃德和拜特斯,
常量标准::函数和函数,
常量标准::向量和参数)
{
//序言
std::tuple args=来自向量的tuple_(params);
标准::应用(函数,参数);
//邮戳
}

你到底想在这里做什么?这段代码的目的是什么?元组将用于什么?在实现中,我使用UINT向量传递的参数调用函数。向量中的类型可能不同于模板参数(T…)。我需要把它们铸造成合适的类型。例如:函数(static_cast(params.at(0)),…)等。在这里使用模板是否合适?请在问题帖中指定参数应该做什么,您希望它如何简化,并尝试给出如何使用N个参数调用函数?有关模板实现的信息,请参阅上面的评论。好的,我不清楚参数是否将被传递到
函数
。刚刚编辑了答案。我将尝试实现并测试您的解决方案。谢谢您的回答。您能修复模板的返回类型吗。@SmitYcyken-抱歉,我不明白。静态无效PIC\u helper返回类型“Out”不是“void”。ProcessIncomingCommand没有返回值。休息好了。请为其他有同样问题的人编辑帖子。
template<typename ResultType, std::size_t... I>
ResultType tuple_from_vector_impl(std::vector<UINT> params, std::index_sequence<I...>)
{
    return std::make_tuple(static_cast<decltype(std::get<I>(std::declval<ResultType>()))>(params[I])...);
}

template<typename... Args, typename Indices = std::index_sequence_for<Args...>>
std::tuple<Args...> tuple_from_vector(std::vector<UINT> params)
{
    return tuple_from_vector_impl<std::tuple<Args...>>(params, Indices{});
}

template<typename Out, typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
                            DWORD & bytesProcessed,
                            const std::function<Out(Args...)> &function,
                            const std::vector<UINT> &params)
{
    // preamble
    std::tuple<Args...> args = tuple_from_vector<Args...>(params);
    Out result = std::apply(function, args);
    // postamble
}

template<typename ... Args>
void ProcessIncomingCommand(PClientContext pClientContext,
                            DWORD & bytesProcessed,
                            const std::function<void(Args...)> &function,
                            const std::vector<UINT> &params)
{
    // preamble
    std::tuple<Args...> args = tuple_from_vector<Args...>(params);
    std::apply(function, args);
    // postamble
}