Jur*_*aho 8 c++ variadic-templates c++11
我想创建一个带有可变数量模板参数的函数.稍后使用这些参数,函数应该像这样传递它们的位置:
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
}
Run Code Online (Sandbox Code Playgroud)
给定的代码当然不可编译.有没有办法解决它?有没有一种方法可以做到没有可变参数模板而没有太多的代码重复?
Dan*_*rey 15
是的,这是可能的:
// 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;
};
Run Code Online (Sandbox Code Playgroud)
有了这些助手,你需要一个代理转发器,如下所示:
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() );
}
Run Code Online (Sandbox Code Playgroud)
编辑:它是如何工作的?首先,我们确定的尺寸参数包 Args通过sizeof....make_indices<N>::type然后扩展到indices<0,1,2,...,N-1>.它作为实现函数的附加参数给出(来自刚刚创建虚拟实例的转发器),因此参数推导在实现函数方面启动并将生成的索引放入参数包中Ns.
实现函数现在有两个具有相同大小的参数包,即Args和Ns.通过...省略号扩展时,省略号会扩展它应用的整个表达式,并且它会并行扩展所有参数包!在上面的表达式中read<Args>(Data, Ns+1),它很好地扩展为OPs伪代码.