我正在尝试围绕使用不透明数据类型的旧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
函数,然后以递归方式传递结果时,我无法弄清楚如何解压缩参数。
有没有这样做?
答案 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并编写类似的扩展函数。