是的,这是可能的:
// 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;
};
使用这些助手,您需要一个转发器来执行您的功能,如下所示:
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() );
}
编辑:它是如何工作的?首先,我们通过确定参数包 的大小。然后扩展为. 它作为实现函数的附加参数(来自刚刚创建一个虚拟实例的转发器),因此参数推导在实现函数方面启动,并将生成的索引放入参数包中。Args
sizeof...
make_indices<N>::type
indices<0,1,2,...,N-1>
Ns
实现函数现在有两个大小相同的参数包,即Args
和Ns
。当通过...
省略号展开时,省略号将展开它所应用的整个表达式,并并行展开所有参数包!在上面的示例中,表达式是read<Args>(Data, Ns+1)
,它很好地扩展为 OP 伪代码。