I however get this error, size...(TSEvents), TSEvents is not declared. Is there anyway for me to access TSEvents in my nested template?
Short answer: no.
Long answer: with
template<
template <typename TSEvent,
typename ...TSEvents> typename V,
typename... Filtered>
constexpr auto filter()
you set two template arguments for the filter()
function.
The first one, related to the TSEvents
variadic list, is a template-template argument that receive one or more types argument.
But your function doesn't receive a type that is based over that template-template (with a fixed TSEvent
type and a fixed TSEvents
); receive the template-template.
So doesn't make sense the test size...(TSEvents)
because, for filter()
isn't
fixed the TSEvents
list.
To explain this in another way... you can call filter this way
filter<std::tuple, short, int, long>();
Ask for sizeof...(TSEvents)
is asking how many types contains std::tuple
where std::tuple
is only the container of types but without contained types.
If you want to make some sort of actions in your filter()
function, you need a type template parameter, not a template-template parameter.
It's simpler with classes (see AndyG's answer) where you can use partial specialization (with functions you can't) or with function when they receive arguments from which you can deduce types.
Suppose your filter()
receive an object of type V<SomeTypes...>
and an object of type std::tuple<Filtered...>
, you can write something as follows (caution: code not tested)
template<
template <typename ...> typename V,
typename TSEvent, typename ... TSEvents, typename... Filtered>
constexpr auto filter (V<TSEvent, TSEvents...> const & v,
std::tuple<Filtered...> const & t) {
/* some code where you can use also TSEvent and TSEvents... */
}
This way TSEvent
and TSEvents...
are deduced from the v
argument.