I have a function which takes one parameter with a default value. Now I also want it to take a variable number of parameters and forward them to some other function. Function parameters with default value have to be last, so... can I put that parameter after the variadic pack and the compiler will detect whether I'm supplying it or not when calling the function?
(Assuming the pack doesn't contain the type of that one last parameter. If necessary, we can assume that, because that type is generally not supposed to be known to the user, otherwise it's considered as wrong usage of my interface anyway....)
template <class... Args>
void func (Args&&... args, SomeSpecialType num = fromNum(5))
{
}
No, packs must be last.
But you can fake it. You can detect what the last type in a pack is. If it is
SomeSpecialType
, you can run your func. If it isn'tSomeSpecialType
, you can recursively call yourself with your arguments forwarded andfromNum(5)
appended.If you want to be fancy, this check can be done at compile time (ie, a different overload) using SFINAE techniques. But that probably isn't worth the hassle, considering that the "run-time" check will be constant on a given overload, and hence will almost certainly be optimized out, and SFINAE shouldn't be used lightly.
This doesn't give you the signature you want, but it gives you the behavior you want. You'll have to explain the intended signature in comments.
Something like this, after you remove typos and the like:
or something much like that.
Another approach would be to pass variadic arguments through a tuple.
Pros : interface is much simpler, overloading and adding default valued arguments is quite easy.
Cons : caller has to manually wrap arguments in a
std::make_tuple
orstd::forward_as_tuple
call. Also, you'll probably have to resort tostd::index_sequence
tricks to implement the function.