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

C++ 可变模板参数的传递位置,c++,c++11,variadic-templates,C++,C++11,Variadic Templates,我想创建一个接受可变数量模板参数的函数。稍后,使用这些参数,函数应按如下方式传递其位置: 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), ...);

我想创建一个接受可变数量模板参数的函数。稍后,使用这些参数,函数应按如下方式传递其位置:

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
}
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() );
}
模板
R myFunction(数据和数据,void*函数){
自动f=(R(*)(Args…)函数;
返回f(read(data,1),read(data,2),…);//是,这是可能的:

// 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;
};
//我们需要一个编译时助手来生成索引
模板
结构索引
{
typedef索引next;
};
模板
结构生成索引
{
typedef typename生成索引::type::next type;
};
模板
结构生成索引<0>
{
类型定义索引类型;
};
使用这些帮助程序,您需要一个转发器来完成以下功能:

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
}
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() );
}
模板
R myFunctionImpl(无效*数据、无效*函数、索引){
自动f=(R(*)(Args…)函数;
返回f(读取
Args
至.
make_index::type
然后展开为
index
。它作为实现函数的附加参数提供(来自仅创建虚拟实例的转发器),因此参数推导在实现函数的一侧起作用,并将生成的索引放入参数包
Ns


实现函数现在有两个大小相同的参数包,即
Args
Ns
。当通过省略号
展开时,省略号展开应用于的整个表达式,并并行展开所有参数包!在上面的示例中,表达式为
读取(数据,Ns+1)
,它很好地扩展为OPs伪代码。

你能发布一个简单的示例吗?我刚刚发布了。我给出的示例缺少什么?缺少的是一个真实的示例。使用
main()
和一些函数(带有1,2,3个参数)。您如何使用这些函数和结构?我花了一些时间才完全理解代码,似乎它应该可以工作。我仍然不明白。这是如何:
typename生成索引::type()
compiles?应该是一个编译错误。我确信您可以避免将对象指针转换为函数指针。@sellibitze:这是一个问题吗?因为我只能有一个从C函数传递的void*指针用户数据。数据可以是
void*
。问题在于函数是
void*
。@JurajBlaho:T他的类型转换非常不可移植。我建议你像那样解释你打算解决什么问题。如果你这样做,你可能会得到更多有用的答案。在我看来,我们有一个X/Y问题。@sellibitze:谢谢你的评论,现在我看到指向
void*
的转换函数指针是UB。我必须解决它虽然有点不同,但我仍然能够使用公认答案中的想法来解决问题。