简体   繁体   English

传递可变参数模板参数的位置

[英]Passing position of variadic template argument

I would like to create a function that takes a variable number of template arguments. 我想创建一个带有可变数量模板参数的函数。 Later with these arguments the function should pass their position like this: 稍后使用这些参数,函数应该像这样传递它们的位置:

template<typename R, typename Args...>
R myFunction(Data &data, void *function) {
    auto f = (R (*)(Args...))function;
    return f(read<Args1>(data, 1), read<Args2>(data, 2), ...);// <-- This is the problem
}

The given code is of course not compilable. 给定的代码当然不可编译。 Is there any way to fix it? 有什么办法可以解决吗? Is there a way to do it without variadic templates without too much code duplication? 有没有一种方法可以做到没有可变参数模板而没有太多的代码重复?

Yes, that is possible: 是的,这是可能的:

// we need a compile-time helper to generate indices
template< std::size_t... Ns >
struct indices
{
  typedef indices< Ns..., sizeof...( Ns ) > next;
};

template< std::size_t N >
struct make_indices
{
  typedef typename make_indices< N - 1 >::type::next type;
};

template<>
struct make_indices< 0 >
{
  typedef indices<> type;
};

With these helpers, you need one forwarder for your function like this: 有了这些助手,你需要一个代理转发器,如下所示:

template<typename R, typename... Args, std::size_t... Ns>
R myFunctionImpl(void *Data, void *function, indices<Ns...> ) {
    auto f = (R (*)(Args...))function;
    return f(read<Args>(Data, Ns + 1)...);// +1 because indices is zero-based
}

template<typename R, typename... Args>
R myFunction(void *Data, void *function) {
   return myFunctionImpl< R, Args... >( Data, function, typename make_indices<sizeof...(Args)>::type() );
}

EDIT: How does it work? 编辑:它是如何工作的? First, we determine the size of the argument pack Args through sizeof... . 首先,我们通过sizeof...确定参数包 Args sizeof... make_indices<N>::type then expands into indices<0,1,2,...,N-1> . make_indices<N>::type然后扩展为indices<0,1,2,...,N-1> It is given as an additional parameter to the implementation function (from the forwarder who just creates a dummy instance), hence argument deduction kicks in on the implementation function's side and puts the generated indices into the argument pack Ns . 它作为实现函数的附加参数给出(来自刚刚创建虚拟实例的转发器),因此参数推导在实现函数侧启动,并将生成的索引放入参数包Ns

The implementation function now has two argument packs with the same size, namely Args and Ns . 实现函数现在有两个具有相同大小的参数包,即ArgsNs When expanded through the ellipsis ... , the ellipsis expands the whole expression that it's applied to and it expands all parameter packs in parallel! 当通过省略号扩展... ,省略号会扩展它应用的整个表达式 ,并且它会并行扩展所有参数包! In the above example that expression is read<Args>(Data, Ns+1) , which nicely expands into the OPs pseudo-code. 在上面的示例中,表达式是read<Args>(Data, Ns+1) ,它很好地扩展为OPs伪代码。

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

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