Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call variadic function in C++ with array as arguments

Suppose I have a simple variadic function like this:

template <typename... A>
void func(A... args)
{
    //Do stuff
}

And I need another function to call the arguments from an array, let's say:

int arg[3] = {1,2,3};

call the function

func(1,2,3);

Is it possible to do this without modifying the templated function?

like image 969
Fynn Avatar asked Jan 25 '16 13:01

Fynn


People also ask

How do you use Variadic arguments?

It takes one fixed argument and then any number of arguments can be passed. The variadic function consists of at least one fixed variable and then an ellipsis(…) as the last parameter. This enables access to variadic function arguments. *argN* is the last fixed argument in the variadic function.

Is printf variadic function?

Variadic functions are functions (e.g. printf) which take a variable number of arguments. The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);.

How does Varargs work in C?

You call it with a va_list and a type, and it takes value pointed at by the va_list as a value of the given type, then increment the pointer by the size of that pointer. For example, va_arg(argp, int) will return (int) *argp , and increment the pointer, so argp += sizeof int .

What is Va_list in C?

va_list is a complete object type suitable for holding the information needed by the macros va_start, va_copy, va_arg, and va_end. If a va_list instance is created, passed to another function, and used via va_arg in that function, then any subsequent use in the calling function should be preceded by a call to va_end.


1 Answers

You could write apply which takes a reference to an array and functor to call with the unpacked array (you might want to add perfect forwarding and such):

template <typename F, typename T, std::size_t N, std::size_t... Idx>
decltype(auto) apply_impl (F f, T (&t)[N], std::index_sequence<Idx...>) {
    return f(t[Idx]...);
}

template <typename F, typename T, std::size_t N>
decltype(auto) apply (F f, T (&t)[N]) {
    return apply_impl(f, t, std::make_index_sequence<N>{});   
}

Then call it like this, if foo is a functor class:

apply(foo{}, a);

If foo is just a normal template function like in your example, you could wrap it in a lambda:

apply([](auto...xs){foo(std::forward<decltype(xs)>(xs)...);}, a);

Live Demo

like image 103
TartanLlama Avatar answered Sep 21 '22 22:09

TartanLlama