0

I need to pass n number of arguments to a function. the user can enter as many arguments as he wants but we don't know the number of arguments he will pass. but all the implementations I have seen using va_list includes a count , but here we dont know the number. it is looks like

        void xyz(int x[],...);

where we have only arrays

the function is used like.

        xyz({1,2,3},{1,1},{2},{3,3,3})

and then I want 3 arrays in my functions in separate variables if possible. I need to do some computation in these arrays. Is this possible in c++??

3 Answers3

1

You can use a variadic function (like printf), but you generally prefer not to.

You can take an initializer_list as a parameter. This will let you take a braced list of items that can all be converted to a single type:

void f(std::initializer_list<int> l);

...which you could call something like:

f({1, 2, 3, 4});

There's also a ctor for std::vector that takes an std::initializer_list, so you can take a (reference to) a vector<T> and accomplish roughly the same. Note, however, that (unlike most parts of C++) this doesn't support narrowing conversions, so for the f above that requires ints, you could get an error if you tried to pass (for example) a double instead.

If you don't like the braces, or want to support the parameters being of different types, you can use a variadic template instead. For example here's a function I posted some time ago to take an arbitrary number of parameters of (nearly) arbitrary type, put them together into a string, and write the resulting string to a socket:

#include <sstream>
#include <string>
#include <iostream>

template <class T>
std::string stringify(T const &t) { 
    std::stringstream b;
    b << t;
    return b.str();
}

template<typename T, typename... Args>
std::string stringify(T arg, const Args&... args) {
    return stringify(arg) + stringify(args...);
}

template<typename... Args>
void send_cmd(const Args&... args) { 
    std::string buffer = stringify(args...);
    send(sock, buffer.c_str(), buffer.length(), 0);
}

int main() {
    std::string three{" three"};

    send_cmd("one: ", 1, " two: ", 2, three, "\n");

    return 0;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0
#include <iostream>
#include <initializer_list>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator>

// Base case: do nothing once all inputs have been processed
void implementation(const std::list<int>& acc) {}

// Recursively pick off one sequence at a time, copying the data into
// the accumulator
template<class ONE, class ... REST>
void implementation(std::list<int>& accumulator,
                    const ONE& first,
                    const REST& ... rest) {
  std::copy(begin(first), end(first), std::back_inserter(accumulator));
  implementation(accumulator, rest...);
}

// Interface, hiding the creation of the accumulator being fed to the
// template-recursive implementation.
template<class ... REST>
std::vector<int> concatenate(const std::initializer_list<REST>& ... rest) {
  std::list<int> accumulator;
  implementation(accumulator, rest...);
  return std::vector<int>(begin(accumulator), end(accumulator));
}

template<class SEQ>
void show_contents(const SEQ& s) {
  std::copy(begin(s), end(s), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
}

int main() {

  show_contents(concatenate({1,2}, {3,4,5}, {6,7}));
  show_contents(concatenate({8,9}));
  show_contents(concatenate({9,8,7}, {6,5}, {4,3}, {2,1}));

}
jacg
  • 2,040
  • 1
  • 14
  • 27
  • So the recursive function is a good way but i want to work on the arrays simultaneously. Like merge all the arrays in one array in increasing order. – user2038791 Oct 10 '14 at 03:07
0

If all the arguments are of the same type, you could pass a std::vector:

void xyz(std::vector<int>& parameters)
{
  //...
}

In your example, it looks like the each parameter may have different quantities of numbers.
This can be handled by using a std::vector< std::vector< int> >:

void abc(std::vector< std::vector< int> >& parameters)
{
  // Each slot of the outer vector is denoted by your {...} syntax.
  std::vector<int>& parameter2 = parameters[1];

  // Each number within {...} is represented by a vector of integers
  std::cout << "{"
            << parameter2[0] << ", "
            << parameter2[1] << ", "
            << parameter2[2]
            << "}\n";
}

Edit 1: Passing parameters

You can place the numbers into variables and pass the variables to the function:

int main(void)
{
  // Load up the individual parameters.
  std::vector<int> p1 = {1};
  std::vector<int> p2 = {2, 3};
  std::vector<int> p3 = {5, 6, 7};

  // Place all parameters into one container
  std::vector< std::vector< int > > parameters = {p1, p2, p3};

  // Call the function with the parameters
  abc(parameters);

  return 0;
}
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154