Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle parameter packs in the middle of a function signature?

I feel a bit uncomfortable at the moment when using parameter packs. I've got a function

template <class ... Args>
void f( int x, Args ... args, int y )
{}

and of course using it like this works:

f( 5, 3 );

I am wondering why the following call fails:

f( 5, 3.f, 3 );

It seems like a straight-forward use of parameter packs to me, but according to the compiler Args is not expanded.

Of course, I could easily replace f by:

template <class ... Args>
void f( int x, Args ... args )
{
    static_assert( sizeof...( args ) >= 1, ... );
    extract y from args ...
}

Questions:

  • Why can't I use parameter packs like this? It seems like the compiler could easily create the replacement code. Or are there any problems with the replacement f() above?

  • What is the best way to deal with this, if the order of the parameters is really important to me? (Think of std::transform for an arbitrary number of input iterators.)

  • Why is the usage of parameter packs not forbidden in the situation above? I assume, it is because they could be expanded explicitly, e.g. f<float>( 5, 3.f, 3 )?

like image 920
Markus Mayr Avatar asked Feb 27 '14 08:02

Markus Mayr


People also ask

What does three dots mean in C++?

Ellipsis in C++ allows the function to accept an indeterminate number of arguments. It is also known as the variable argument list.

What is Variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.

What is parameter pack in c++?

Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.

What are Variadic functions in C?

Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.


1 Answers

Why can't I use parameter packs like this? It seems like the compiler could easily create the replacement code. Or are there any problems with the replacement f() above?

Might be easy in this particular case, might not be in others. The real answer is that the Standard specifies the behavior and the Standard did not specify any transformation... and in general rarely does.

I would note that your transformation does not work with SFINAE, since static_assert are hard-errors, so I am glad the transformation is not performed. (Hint: what if f is overloaded with a single-argument version taking a float, which would get chosen with/without transformation for f(1) ?)

What is the best way to deal with this, if the order of the parameters is really important to me? (Think of std::transform for an arbitrary number of input iterators.)

Explicitly specifying the template pack parameters.

Why is the usage of parameter packs not forbidden in the situation above? I assume, it is because they could be expanded explicitly, e.g. f( 5, 3.f, 3 )?

I think that your assumption is spot on; if explicitly specified this works as expected.

like image 92
Matthieu M. Avatar answered Oct 21 '22 03:10

Matthieu M.