Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass container values to a variadic function?

Tags:

c++

c++11

I have a template variadic function:

template <typename ... argsType>
static bool Call(std::string const& Key, argsType&& ... Args)
{
    /* ... */
}

This is called for example like this:

Call("add2", 1, 2);
Call("add3", 1, 2, 3);
Call("true", true);

Then I also have different containers with a variable number of elements:

std::vector<int> v1 = {1, 2};
std::vector<int> v2 = {1, 2, 3};
std::vector<bool> v3 = {true};

Now is there any way to call the variadic function with the values of these containers, or do I have to change that function so that it accepts containers as parameter? If possible I would like to do something like this:

Call("add2", /* use v1 here */);
Call("add3", /* use v2 here */);
Call("true", /* use v3 here */);
like image 465
Matthias Avatar asked Jan 26 '26 17:01

Matthias


1 Answers

No, you cannot. The number of elements in a vector is a runtime quantity, and the number of arguments passed to a function is a compile-time quantity. The only way to unpack a vector into a function like that is through something like a giant switch statement:

switch (v.size()) {
case 0: Call("add2"); break;
case 1: Call("add2", v[0]); break;
case 2: Call("add2", v[0], v[1]); break;
// ...
}

which can be generated with the help of index_sequence but only if you know what the limit of v.size() actually is.

What you would typically do instead is just pass in a pair of iterators:

template <class Iter>
static bool Call(std::string const& Key, Iter first, Iter last);

Call("add2", v.begin(), v.end());

Or collapse that into something like gsl::span:

template <class T>
static bool Call(std::string const& Key, gsl::span<T> values);

Call("add2", gsl::span<int>{v});
like image 187
Barry Avatar answered Jan 28 '26 08:01

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!