Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I inherited a lot of C code with many ellipsis (variadic) function.

So 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, how can I replace it with a typesfe C++ API, and I came up with the following:

#include <string>
#include <iostream>
#include <cstdarg>
#include <vector>

class Test
{
  struct GetParam
    {
      std::string name;
      int id;
    };
  struct Attr
    {
      Attr(Test& test) : test(test)
        {
          std::cout << "Attr()" << std::endl;
          test.get_params.clear();
        }
      ~Attr()
        {
          std::cout << "~Attr()" << std::endl;
          test.end_get();
        }
      Attr& add(const std::string& name, int id)
        {
          GetParam param = {name, id};
          test.get_params.push_back(param);
          return *this;
        }
      Test& test;
    };
  void end_get()
    {
      for (auto get_param : get_params)
        std::cout << "name:" << get_param.name << ", id:" << get_param.id << std::endl;
    }
  std::vector<GetParam> 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 << "name:" << name << ", id:" << id << 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?

share|improve this question

1 Answer 1

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));
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.