Luca Davanzo
Luca Davanzo

Reputation: 21528

C++ method that takes N parameters

Saying that I have my A class with foo(...) method where:

... => stands for a variable number of parameters

I want to save all this parameters on a std::vector.

I've try with:

std::vector<std::string> A::foo(...) {
  std::vector<std::string> list;
  va_list args;
  va_start(args, 0); 
  for ( ; /* which condition to exit? */ ; ) {
      std::string s = va_arg(args, char*);
      list.push_back(s);
  }
  return list;
}

Obviously this can't works, but I can't figure out how can I fill s string and understand when exit from cicle.

In main I will call foo in this way:

foo("param0", "param1", "param2", ... , "paramN")

Upvotes: 0

Views: 135

Answers (2)

ecatmur
ecatmur

Reputation: 157414

The correct way to write A::foo is to write it as a C++11 variadic template:

template<typename... Args>
std::vector<std::string> A::foo(Args&& ...args) {
    return {std::forward<Args>(args)...};
}

If this isn't an option, you can accept up to a fixed number of arguments using default arguments:

std::vector<std::string> A::foo(
    const char* arg1 = 0,
    const char* arg2 = 0,
    // ...
    const char* arg10 = 0)
{
    std::vector<std::string> ret;
    if (arg1) ret.push_back(arg1); else return ret;
    if (arg2) ret.push_back(arg2); else return ret;
    // ...
    if (arg10) ret.push_back(arg10); else return ret;
    return ret;
}

You can use a preprocessing library e.g. Boost.Preprocessor to automate generation of the repeated parameters and parameter handlers.

Upvotes: 2

Edward
Edward

Reputation: 304

You should somehow pass to the function count of arguments. For example look at int printf ( const char * format, ... );. The function parses format string and determines how many arguments have been provided. You can change your code to something like this:

std::vector<std::string> A::foo(size_t count, ...) {
  std::vector<std::string> list;
  va_list args;
  va_start(args, 0); 
  for ( size_t i = 0; i < count; ++i ) {
      std::string s = va_arg(args, char*);
      list.push_back(s);
  }
  return list;
}

Upvotes: 2

Related Questions