Most of the questions I have found revolve around non-member functions where the variadic template parameters are also found in the function's arguments.
In my case, I am in a situation where I would like to filter the types coming into one of the variadic member functions and pass the filtered types to another variadic member function:
#include <tuple>
#include <type_traits>
template<typename...Ts>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));
// how the filtering of the types happen is not relevant
template<typename T, typename...Ts>
using remove_t = tuple_cat_t<
typename std::is_empty_v<T>,
std::tuple<>,
std::tuple<Ts>
>::type...
>;
struct Foo
{
template <typename... T_Tags>
void Bar(float arg)
{
// I would like to call DoBar() with a filtered set of T_Tags
// where type filtering is done with something similar to what is outlined
// here: https://stackoverflow.com/a/23863962/368599
using filtered_args = std::remove_t<T_Tags...>;
// not sure of the syntax here or if this is even possible
std::invoke(&Foo::DoBar<???filtered_args???>, std::tuple_cat(std::make_tuple(this), std::make_tuple(arg)));
}
template <typename... T_FilteredTags>
void DoBar(float arg)
{
// Do something with T_FilteredTags types
}
};
You can use template lambda to expand the filtered types and specify them to DoBar
explicitly
struct Foo
{
template <typename First_Tag, typename... T_Tags>
void Bar(float arg)
{
using filtered_args = remove_t<First_Tag, T_Tags...>;
[&]<typename... T_FilteredTags>(std::tuple<T_FilteredTags...>*) {
std::invoke(&Foo::DoBar<T_FilteredTags...>, this, arg);
} (static_cast<filtered_args*>(nullptr));
}
template<typename... T_FilteredTags>
void DoBar(float arg)
{
// Do something with T_FilteredTags types
}
};
Noted that there is no need to use tuple
to concatenate this
and arg
, just pass them to std::invoke
directly.