Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unpacking Argument List with Variadic Template

I'm trying to create a C++ convenience wrapper around an old C-API that uses an opaque data type. There's one particular C-function which takes a format string, along with a variable number of arguments using the C <stdarg.h> facilities. As part of my wrapper, I want to be able to pass an arbitrary number of arguments (including C++ objects) to this function. However, since obviously the <stdarg.h> facilities can't work with non-POD data, I created a templated conversion function which converts C++ objects (like std::string) into POD equivalents.

I thought this whole thing would be an easy exercise using C++0x variadic templates, but I'm having difficulty figuring out how to write this function in a way that properly unrolls the argument pack while applying my conversion function to each argument.

What I have so far is:

   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...);
   }

Of course, this doesn't work because the recursive function call never actually unpacks the Args..., so it just recurses until the stack overflows. I can't figure out how to make it unpack the arguments while also passing the current argument to the Convert function, and then recursively passing along the result.

Is there anyway to do this?

like image 642
Channel72 Avatar asked Feb 07 '11 21:02

Channel72


People also ask

How do you use Variadic arguments?

In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed. The variadic function consists of at least one fixed variable and then an ellipsis(…) as the last parameter. This enables access to variadic function arguments.

What is the use of Variadic templates?

With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.

What is Variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.


1 Answers

I think you need the same syntax as when you do perfect forwarding :

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))...);
}

The ellipsis ... can be placed at the right of an expression containing the argument pack, and not only directly at the right of the argument pack itself.

So, :
func(args...) expand to func(arg1, arg2, arg3, [...] , argN)
func(args)... expand to func(arg1), func(arg2), [...] , func(argN)

like image 102
Thomas Petit Avatar answered Oct 18 '22 22:10

Thomas Petit