Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable number of parameters in function in C++

How I can have variable number of parameters in my function in C++.

Analog in C#:

public void Foo(params int[] a) {     for (int i = 0; i < a.Length; i++)         Console.WriteLine(a[i]); }  public void UseFoo() {     Foo();     Foo(1);     Foo(1, 2); } 

Analog in Java:

public void Foo(int... a) {     for (int i = 0; i < a.length; i++)         System.out.println(a[i]); }  public void UseFoo() {     Foo();     Foo(1);     Foo(2); } 
like image 723
AndreyAkinshin Avatar asked Oct 16 '09 18:10

AndreyAkinshin


People also ask

What is variable number of arguments in C?

To call a function with a variable number of arguments, simply specify any number of arguments in the function call. An example is the printf function from the C run-time library. The function call must include one argument for each type name declared in the parameter list or the list of argument types.

How many parameters can a function have in C?

The maximum number of arguments (and corresponding parameters) is 253 for a single function.

What is the syntax of variable number of parameters?

Syntax of VarargsA variable-length argument is specified by three periods or dots(…). This syntax tells the compiler that fun( ) can be called with zero or more arguments. As a result, here, a is implicitly declared as an array of type int[].

What are the parameters of a function in C?

Parameters in C functions A Parameter is the symbolic name for "data" that goes into a function. There are two ways to pass parameters in C: Pass by Value, Pass by Reference.


2 Answers

These are called Variadic functions. Wikipedia lists example code for C++.

To portably implement variadic functions in the C programming language, the standard stdarg.h header file should be used. The older varargs.h header has been deprecated in favor of stdarg.h. In C++, the header file cstdarg should be used.

To create a variadic function, an ellipsis (...) must be placed at the end of a parameter list. Inside the body of the function, a variable of type va_list must be defined. Then the macros va_start(va_list, last fixed param), va_arg(va_list, cast type), va_end(va_list) can be used. For example:

#include <stdarg.h>  double average(int count, ...) {     va_list ap;     int j;     double tot = 0;     va_start(ap, count); //Requires the last fixed parameter (to get the address)     for(j=0; j<count; j++)         tot+=va_arg(ap, double); //Requires the type to cast to. Increments ap to the next argument.     va_end(ap);     return tot/count; } 
like image 197
Stephan202 Avatar answered Sep 28 '22 04:09

Stephan202


The real C++ solution is variadic templates. You'll need a fairly recent compiler and enable C++11 support if needed.

Two ways to handle the "do the same thing with all function arguments" problem: recursively, and with an ugly (but very very Standards compliant) solution.

The recursive solution looks somewhat like this:

template<typename... ArgTypes> void print(ArgTypes... args); template<typename T, typename... ArgTypes> void print(T t, ArgTypes... args) {   std::cout << t;   print(args...); } template<> void print() {} // end recursion 

It generates one symbol for each collection of arguments, and then one for each step into the recursion. This is suboptimal to say the least, so the awesome C++ people here at SO thought of a great trick abusing the side effect of a list initialization:

struct expand_type {   template<typename... T>   expand_type(T&&...) {} }; template<typename... ArgTypes> void print(ArgTypes... args) {    expand_type{ 0, (std::cout << args, 0)... }; } 

Code isn't generated for a million slightly different template instantiations, and as a bonus, you get preserved order of you function arguments. See the other answer for the nitty gritty details of this solution.

like image 24
rubenvb Avatar answered Sep 28 '22 03:09

rubenvb