Function Taking a Variable Number of Arguments

Variable number of arguments in C programmng

I want to use functions like sum(1,2,3) should return 6. i.e, no counter should be there

You could define a sentinel. In this case 0 might make sense.

/* Sums up as many int as required. 
Stops adding when seeing the 1st 0. */
int sum(int i, ...)
{
int s = i;

if (s)
{
va_list ap;

va_start(ap, i);

/* Pull the next int from the parameter list and if it is
equal 0 leave the while-loop: */
while ((i = va_arg(ap, int)))
{
s += i;
}

va_end(ap);
}

return s;
}

Call it like this:

int sum(int i, ...);

int main(void)
{
int s = sum(0); /* Gives 0. */

s = sum(1, 2, 3, 0); /* Gives 6. */
s = sum(-2, -1, 1, 2, 0); /* Gives 0. */
s = sum(1, 2, 3, 0, 4, 5, 6); /* Gives 6. */

s = sum(42); /* Gives undefined behaviour! */
}

The sum() function alternatively could also look like this (but would do one useless addition of 0):

/* Sums up as many int as required. 
Stops adding when seeing the 1st 0. */
int sum(int i, ...)
{
int s = i;

if (s)
{
va_list ap;

va_start(ap, i);

/* Pull the next int from the parameter list and if it is
equal 0 leave the do-loop: */
do
{
i = va_arg(ap, int);
s += i;
} while (i);

va_end(ap);
}

return s;
}

Using a function with a variable number of arguments

You can use variadic templates. One example for printing out all the passed argument is given below:

#include <iostream>
//provide an ordinary function to end recursion
void print ()
{
}

template<typename T, typename... Types>
void print (T firstArg, Types... args)
{
std::cout << firstArg << "\n"; // printing the very first argument passed
print(args...); // printing the rest of the argument by calling print()
}

int main()
{
print(1, 2, 3, "some string literal");//call function template print() with arguments `1`, `2`, `3` and `"some string literal"`
return 0;
}

In the above snippet, if we call print() with one or more arguments then the templated version of print will be used/called which just prints the very first argument passed(which is 1 in my example) using cout and then calls print with the remaining arguments(which are 2, 3 and "some string literal.

Now the whole process repeats. In particular, the very first argument 2 is printed using cout and then print is called with the remaining arguments(3, "some string literal").

This goes on until there are no more arguments to pass and in this case when print is called with no arguments then the ordinary non-template function print will be used/chosen, thus ending the recursion.

The output of the above program can be seen here:

1
2
3
some string literal

Note that there are other ways as well like using fold expression(with C++17) to do the same. Also, in the above example, the arguments are passed by value. You can modify the program to pass them by reference according to your needs.

With C++17, you can use fold expression:

#include <iostream>
template<class... Args>
void print(const Args&... args)
{
(std::cout << ... << args) << "\n"; //uses fold expression
}

int main()
{
print(1, 2, 3, "some string literal");
return 0;
}

Variable number of Arguments in C?

int ff(int num, ...)
{
va_list arguments;
int sum = 0;
va_start(arguments, num);
for (int x = 0; x < num; x++)
{
sum += va_arg(arguments, int);
}
va_end(arguments);

return sum;
}

//call
printf("%d\n", ff(3, 1, 2, 3));

va_list contains list of arguments in ..., in loop you get access one by one va_arg(arguments, int);

Can a variable number of arguments be passed to a function?

Yes. You can use *args as a non-keyword argument. You will then be able to pass any number of arguments.

def manyArgs(*arg):
print "I was called with", len(arg), "arguments:", arg

>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)

As you can see, Python will unpack the arguments as a single tuple with all the arguments.

For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.

How can I take a variable number of arguments into a function and use them as indices?

I believe this is what you are looking for:

In [10]: def doit(s, *indices):
...: return tuple(s[i] for i in indices)

In [11]: doit("tremendous", 1, 3, 5, 7)
Out[11]: ('r', 'm', 'n', 'o')

See this SO question about "tuple comprehensions".

Creating a function in R with variable number of arguments,

d <- function(...){
x <- list(...) # THIS WILL BE A LIST STORING EVERYTHING:
sum(...) # Example of inbuilt function
}

d(1,2,3,4,5)

[1] 15

Pass a variable number of arguments into a function

You can expand the array using a std::index_sequence

#include <iostream>
#include <utility>

struct A {
A(int a, int b) : x(a), y(b) {}
int x, y;
};

struct B {
B(int a, int b, int c) : x(a), y(b), z(c) {}
int x, y, z;
};

template<typename T, typename... TArgs>
T* createElement(TArgs&&... MArgs) {
T* element = new T(std::forward<TArgs>(MArgs)...);
return element;
}

template<typename T, typename U, size_t... I>
T* createElementFromArrayHelper(std::index_sequence<I...>, U* a){
return createElement<T>(a[I]...);
}

template<typename T, typename U, size_t N>
T* createElementFromArray(U (&a)[N]){
return createElementFromArrayHelper<T>(std::make_index_sequence<N>{}, a);
}

int main() {

int Aargs[] = { 1, 2 };
int Bargs[] = { 1, 2, 3 };

A* a = createElementFromArray<A>(Aargs);
B* b = createElementFromArray<B>(Bargs);

std::cout << "a.x: " << a->x << "\na.y: " << a->y << "\n" << std::endl;
std::cout << "b.x: " << b->x << "\nb.y: " << b->y << "\nb.z: " << b->z << "\n" << std::endl;

delete a;
delete b;

}

Calling function with variable number of arguments from a function with a variable number of arguments

Yes:

va_list args;
va_start(args, text);

vprintf(format_goes_here, args);

You can find info about vprintf here (or check your man pages).

I've done similar for wrapping functions such as write (Unix) and OutputDebugString (Windows) so that I could create a formatted string to pass to them with vsnprintf.

EDIT: I misunderstood your question. No you can't, at least not in C. If you want to pass the variable number of arguments on, the function you're calling must take a va_list argument, just like vprintf does. You can't pass your va_list onto a function such as printf(const char *fmt,...). This link contains more information on the topic.

If the function does take a va_list argument, then you can pass arguments from a specific point (ie. you might to skip the first one). Retrieving arguments with va_arg will update the va_list pointer to the next argument, and then when you pass the va_list to the function (such as vprintf), it'll only be able to retrieve arguments from that point on.

JavaScript variable number of arguments to function

Sure, just use the arguments object.

function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}


Related Topics



Leave a reply



Submit