Home > Mobile >  How to use "type ... pack-name" parameter pack in C ?
How to use "type ... pack-name" parameter pack in C ?

Time:11-06

The cppreference page on parameter pack states there is a parameter pack like this:

type ... pack-name(optional)    (1)

But how do you use it?

This doesn't work and the error is syntactical:

template<int... Ints>
int sum_2_int(Ints... args)
{
    return (int)(args   ...);
}

I can't figure out how to use this thing from the description and I don't see an example of the usage anywhere on that page. I may have just skipped it because I am very inexperienced in this part of c .

EDIT1: I am not trying to sum an arbitrary amount of integers or whatever types. I've written this function because of my complete lack of understanding of how and where to use this type of parameter pack since I assumed it will be similar to the type (2) typename|class ... pack-name(optional).

EDIT2: Now I know that trying to use Ints... args as a parameter in function definition is futile. I made a new snippet, that works now here. If you know more examples of the usage of this type of parameter pack, please share.

CodePudding user response:

So, what I've learned about type (1) parameter pack:

  1. It is INCORRECT to use as a parameter in the function definition, since template<int... Ints> int foo(...) {...} just means that you should later use your function as int i = foo<1,2,3,4,...>(...);
  2. It can be used as an argument to some function after the expansion happens:
// parameter pack type [2] typename|class ... pack-name(optional)
template <typename... Types>
int sum_to_int(Types... args)
{
    return (int)(args   ...); // fold expression used here
}

// parameter pack [1] type ... pack-name(optional)
template <int... Ints>
int sum_ints_statically()
{
    return sum_to_int(Ints...);
}

int main()
{
    return sum_ints_statically<1,2,3,4,5>(); // will return 15!
}

Thanks Evg and user17732522 for helping me to find the answer.

Please add more usage examples if you know more!

CodePudding user response:

It looks like your function is meant to sum a list of ints. You can provide this list directly with a non-type template parameter pack and no normal parameter or with a type template parameter pack used for the normal parameter types. Not both at the same type. Examples:

template<int... Ints>
int sum_2_int()
{
    return (int)(Ints   ...);
}

sum_2_int<1, 2, 3>(); // template arguments must be known at compile time
template<typename... Ints>
int sum_2_int(Ints... args)
{
    return (int)(args   ...);
}

sum_2_int(1, 2, 3); // function arguments must be summable

Demo

Note that the second version accepts any type for each of the parameters, but you can constrain them with std::enable_if or C 20 concepts.

To answer your edit: the first version above is exactly how you can use such a parameter pack. Note the expression is (Ints ...) instead of (args ...).

You can also have a look at std::integer_sequence, particularly the alias index_sequence and the examples in that page.

I also found this specific application for computing fibonacci numbers at compile-time.

  • Related