Are you sure the first Error is the one reported? I would expect 'contains': too few template arguments since the declaration requires at least two and lines 9 and 17 may attempt to instantiate one with fewer arguments.
Does this work for you?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
template <typename T, typename First=void, typename... Rest>
struct contains
{
staticconstexprbool value = std::is_same<T, First>::value || contains<T, Rest...>::value;
};
template <typename T>
struct contains<T, void>
{
staticconstexprbool value = false;
};
template <typename T, typename... Forbidden>
struct gforbidden_types
{
static_assert(!contains<T, Forbidden...>::value, "Cannot instantiate forbidden_types object with a forbidden type");
using type = T;
};
Are you sure the first Error is the one reported? I would expect 'contains': too few template arguments since the declaration requires at least two and lines 9 and 17 may attempt to instantiate one with fewer arguments.
Yes. To be honest I've never liked how MSVC reports template-related errors.
This is what g++ says, which is clearer:
1 2
error: wrong number of template arguments (1, should be at least 2)
struct contains<T> on line 9
Does this work for you?
Yes, it works! Thanks!
I see you defaulted the template parameter to void, and then specialized it to return false in case it is void (which happens when the parameter pack becomes empty)
I suppose the template function version is just overloading the function, whereas with structs/classes I need specialization which uses that different syntax, right?