C-style va_args replacement I inherited a lot of C code with many ellipsis (variadic) functions.

I have a lots of API with the following signature:

void getXY(int foo, ...) // many parameters


and this is used in this way as usual:

getXY(1, "sizex", 12, "sizey", 24, 0);


Now I started to think about how I can replace it with a typesafe C++ API, and I came up with the following:

#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;cstdarg&gt;
#include &lt;vector&gt;

class Test
{
  struct GetParam
    {
      std::string name;
      int id;
    };
  struct Attr
    {
      Attr(Test&amp; test) : test(test)
        {
          std::cout &lt;&lt; "Attr()" &lt;&lt; std::endl;
          test.get_params.clear();
        }
      ~Attr()
        {
          std::cout &lt;&lt; "~Attr()" &lt;&lt; std::endl;
          test.end_get();
        }
      Attr&amp; add(const std::string&amp; name, int id)
        {
          GetParam param = {name, id};
          test.get_params.push_back(param);
          return *this;
        }
      Test&amp; test;
    };
  void end_get()
    {
      for (auto get_param : get_params)
        std::cout &lt;&lt; "name:" &lt;&lt; get_param.name &lt;&lt; ", id:" &lt;&lt; get_param.id &lt;&lt; std::endl;
    }
  std::vector&lt;GetParam&gt; get_params;

public:
  // old code
  void get1(int foo, ...)
    {
      va_list args;
      va_start(args, foo);
      const char* name = va_arg(args, const char *);
      for (; name != NULL; name = va_arg(args, const char *))
        {
          int id = va_arg(args, int);
          std::cout &lt;&lt; "name:" &lt;&lt; name &lt;&lt; ", id:" &lt;&lt; id &lt;&lt; std::endl;
        }
      va_end(args);
    }

  // new code plan
  Attr get2(int foo)
    {
      Attr attr(*this);
      return attr;
    }
private:
};

int main()
{
  Test test;
  test.get1(1, "sizex", 12, "sizey", 24, 0); // old style
  test.get2(1).add("sizex", 12).add("sizey", 24); // new style
  return 0;
}


What do you think? Is there a simpler solution? How can I improve this?
If the arguments are that simple, what's wrong with a locally defined array?

Test t;
const Test args[] = { {"sizex", 12}, {"sizey", 24} };
t.get(1, args, sizeof(args)/sizeof(*args));