使用Variadic模板解压缩参数列表

时间:2011-02-07 21:15:09

标签: c++ c++11 variadic-functions

我正在尝试围绕使用不透明数据类型的旧C-API创建C ++便捷包装器。有一个特定的C函数,它使用格式字符串,以及使用C <stdarg.h>工具的可变数量的参数。作为我的包装器的一部分,我希望能够将任意数量的参数(包括C ++对象)传递给此函数。但是,由于<stdarg.h>设施显然无法处理非POD数据,因此我创建了一个模板化转换函数,它将C ++对象(如std::string)转换为POD等价物。

我认为使用C ++ 0x可变参数模板这一切都很简单,但我很难弄清楚如何以适当展开参数包的方式编写此函数,同时将转换函数应用于每个模板参数。

到目前为止我所拥有的是:

   template <class T, class... Args>
   void apply(OPAQUE* object, const char* fmt_string, T&& val, Args&&... args)
   {
      apply(object, fmt_string, Convert(val), args...);
   }

   template <class... Args>
   void apply(OPAQUE* object, const char* fmt_string, Args&&... args)
   {
      C_API_Function_Call(object, fmt_string, args...);
   }

当然,这不起作用,因为递归函数调用永远不会实际解包Args...,所以它只是递归直到堆栈溢出。当将当前参数传递给Convert函数,然后以递归方式传递结果时,我无法弄清楚如何解压缩参数。

有没有这样做?

2 个答案:

答案 0 :(得分:25)

我认为您需要与完成转发时相同的语法:

template <class... Args>
void apply(OPAQUE* object, const char* fmt_string, Args&&... args)
{
   C_API_Function_Call(object, fmt_string, Convert(std::forward<Arg>(args))...);
}

省略号...可以放在包含参数包的表达式的右侧,而不仅仅是直接位于参数包本身的右侧。

所以,:
func(args ...)展开到func(arg1,arg2,arg3,[...],argN)
func(args)...扩展为func(arg1),func(arg2),[...],func(argN)

答案 1 :(得分:-1)

目前,C ++ 0x草案没有为此提供任何解决方案。因为问题类似于扩展元组,所以您可以阅读this discussion并编写类似的扩展函数。