-1

In Java we have variable arguments 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[].

class Test1
{
    // A method that takes variable number of integer
    // arguments.
    static void fun(int ...a)
    {
        System.out.println("Number of arguments: " + a.length);
  
        // using for each loop to display contents of a
        for (int i: a)
            System.out.print(i + " ");
        System.out.println();
    }
  
    // Driver code
    public static void main(String args[])
    {
        // Calling the varargs method with different number
        // of parameters
        fun(100);         // one parameter
        fun(1, 2, 3, 4);  // four parameters
        fun();            // no parameter
    }
}

I am looking to implement the same thing in C++ but I couldn't find anything useful. Does anyone have any ideas?

Sumit Jaiswal
  • 216
  • 1
  • 4
  • 17
  • there's only varags in C++, but it's untyped – phuclv Aug 04 '21 at 03:11
  • @xskxzr it seem relevant but I don't understand much of it. – Sumit Jaiswal Aug 04 '21 at 03:16
  • @phuclv That question is about Python, not C++. – chrylis -cautiouslyoptimistic- Aug 04 '21 at 03:18
  • 1
    @chrylis-cautiouslyoptimistic- yeah I didn't read it carefully. Real duplicates: [C++11 variable number of arguments, same specific type](https://stackoverflow.com/q/18017543/995714), [Variable number of parameters in function in C++](https://stackoverflow.com/q/1579719/995714), [Variable number of arguments in C++?](https://stackoverflow.com/q/1657883/995714) – phuclv Aug 04 '21 at 03:24
  • @phuclv It's surprising that there are so many such problems. Please close them as duplicates (or form a duplicate chain) to help future readers. – xskxzr Aug 04 '21 at 03:33
  • 1
    If the parameters are known at compile time, you probably want a [parameter pack](https://stackoverflow.com/a/27471566/4581301). If you don't know until runtime, push the parameters into a `std::vector` and then pass in the `vector`. There is no easy, do it all for you solution in C++ mostly because it would pretty much be the `vector` option hidden behind a layer of [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar), and C++ frowns on hiding something that could have significant overhead. – user4581301 Aug 04 '21 at 03:36

4 Answers4

4

From C++11 and above, you can use parameter packs and store them in a std::initializer_list:

#include <iostream>
#include <initializer_list>

template <typename ...Args>
void fun(Args const&... args) {
    std::initializer_list<int> arg_list { args... };
    std::cout << "Number of arguments: " << arg_list.size() << std::endl;

    for (auto const& i : arg_list)
        std::cout << i << " ";
    std::cout << std::endl;
}

int main() {
    // Calling the varargs method with different number
    // of parameters
    fun(100);         // one parameter
    fun(1, 2, 3, 4);  // four parameters
    fun();            // no parameter
    // fun(1, "");    // Error
}
Ruks
  • 3,886
  • 1
  • 10
  • 22
  • 1
    What I do in this situation is similar to this. But instead of an `initializer_list` variable, I prefer a simple C array. And then this array together with `sizeof...(args)` is passed to a private non-template function that implements the feature. Something like `const int arg_list[]{ args... }; fun_impl(arg_list, sizeof...(args));` Advantage: there is only one instantiation of the work function whatever the number of different template arguments. – prapin Aug 04 '21 at 07:06
2

You are looking for a variadic function. Note that because of the way that these are implemented in C++, actually consuming the arguments requires a fairly complex series of macro invocations, in contrast to Java's practice of simply converting the arguments into an array (which can report its own length).

Variadic templates are a similar concept but operate by essentially performing automated copy-and-paste to actually create multiple distinct functions at compile time.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
1

I think it's a good example for you ! And details

#include <iostream>
#include <cstdarg>
void simple_printf(const char* fmt...) // C-style "const char* fmt, ..." is also valid
{
    va_list args;
    va_start(args, fmt);
 
    while (*fmt != '\0') {
        if (*fmt == 'd') {
            int i = va_arg(args, int);
            std::cout << i << '\n';
        } else if (*fmt == 'c') {
            // note automatic conversion to integral type
            int c = va_arg(args, int);
            std::cout << static_cast<char>(c) << '\n';
        } else if (*fmt == 'f') {
            double d = va_arg(args, double);
            std::cout << d << '\n';
        }
        ++fmt;
    }
 
    va_end(args);
}
int main()
{
    simple_printf("dcff", 3, 'a', 1.999, 42.5); 
}
0

If you want to use multiple int arguments, and you know the max number of the them, you can use default value. For example:

void fun(int arg1=0,int arg2=0,int arg3=0,int arg4=0)
{
    ...
}

Or you can refer to the declaration of main function:

int main(int argc,char* argv[]) 

define the function like it:

void fun(int argc, int* argv[])
{
    ...
}
cpvmrd
  • 51
  • 4