view raw
Jacob Krieg Jacob Krieg - 8 months ago 45
C++ Question

Limit the number of parameters in a variadic template parameter pack

I have a template function that takes a variable number of arguments. Since you can't force the arguments to be of a certain type I would like at least to force the number of arguments not to be higher that a compile-time determined number(e.g. 10).

Is it possible to make to compiler give an error if a template function with a parameter pack has the number of arguments higher than a compile-time determined value?

template <class ...Args>
void setRequestArguments(const Args&... args)
const std::vector<QGenericArgument> vec = { args... };
qDebug() << sizeof...(args);
// Do stuff...
// for (unsigned i = 0; i < vec.size(); ++i) {
// qDebug() << vec[i].name();
// }

What I want to use it for is for a generic container for all arguments in an
wrapper function.


To make the function not callable when there's too much arguments, you can constraint the function with sfinae. That way, if there's another overload that accept more argument, the compiler will be able to select the correct overload.

A simple std::enable_if with the condition will suffice:

template <class ...Args, std::enable_if_t<(sizeof...(args) <= 10), int> = 0>
void setRequestArguments(Args&&... args)
    const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };

For the sake of lisibility, you can put the constraint in the trailing return type of your function:

template <class ...Args>
auto setRequestArguments(Args&&... args) -> std::enable_if_t<(sizeof...(args) <= 10)>
    const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };

EDIT: I added forwarding reference instead of const reference, since it can speed up the program and is more friendly to non copiable types.