Variadic Templates - Understanding Parameter Package Extension

I am having a hard time understanding the parameter pack extension. What confuses me is that dots appear on the right side and dots appear on the left side. I ran into this which helped a little. Suppose I have the following two examples:

Example 1:
template <class ...A>   --> line 1
int func(A... arg)      --> line 2
{
   return sizeof...(arg);
}

int main(void)
{
   return func(1,2,3,4,5,6);
}

      

The post I mentioned above, I believe the difference is b / w ...A

and A...

is that the first has an extension on the left side and the second has a right side extension. I'm not sure what that means. Can anyone please clarify this with how something would look when expanded. The only thing I understand so far regarding the points on the right side are examples like

//Foo and bar are variadic parameter packs
Foo...                     => Foo1, Foo2, Foo3, etc
std::vector<Foo>...        => std::vector<Foo1>, std::vector<Foo2>, std::vector<Foo3>, etc.
std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc)
&bar...                    => &bar1, &bar2, &bar3, etc

      

Can anyone please clarify that dots are expanding on line 1 and line 2 and what is the difference between expanding the left side and expanding the right side?

+3


source to share


1 answer


There is no "left extension", there is only "extension to the right". When you typed:

template <class ...A>
int func(A... arg)

      

...

does not apply to A

. It helps to think of it like:

 template <class... A>

      

As in, A

names the parameter package consisting of class

es. There is no extension on this line, it's just a parameter declaration for the function template func

.



Also, as TC points out , ...

in the argument list is grammatically bound to the argument name, not the type. This helps you understand particularly complex declarations such as:

template <typename... T>
void foo(T (*...fs)());

      

where fs

would be a (possibly empty) package of pointers to null functions.

As for the option pack extension, see my answer here for a list of examples of which option package extension is based on placement ...

. Short version: all packages in the expression immediately preceding ...

are expanded at the same time. All examples listed in your question are correct. I would add:

std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc)
std::tuple<Foo>(bar)...    => std::tuple<Foo1>(bar1), std::tuple<Foo2>(bar2), ...

      

+2


source







All Articles