Let's say we have a wrapping template function (or member function) like this:
template <class... T> void f(T... args) {
_f(args...);
}
void _f(int a1, ...); // variadic old style function
Where the function _f
(defined in a third-party library that we cannot modify) accepts several combinations of parameter types and it would be desirable to limit possible parameters at wrap level.
If we have hundreds of such functions with different possible parameter types it would be too bulky to manually define the overloaded functions with named arguments. It would be better to define such functions using simple macro with lists of possible types. Boost's macros that allows to iterate argument's lists to construct named arguments looks too heavy.
Is there an elegant way to limit possible arguments at declaration level?
You can use traits to define accepted lists of parameters based on their types.
It follows a minimal, working example:
The last invokation will give you a compile time error for
<int, int, int>
isn't a valid specialization of structaccepts
.This is because the primary template isn't defined and you can control the accepted lists by introducing more and more specializations if needed.
Here is a slightly different solution based on
std::true_type
,std::false_type
andstatic_assert
:Advantages are:
"!"
with something meaningful)std::false_type
and document it at the same time if neededThe disadvantage is that it's a bit more verbose.