I'm searching for a way to remove (let's say for now all occurences of) a type from a template parameter pack. The end result would be a struct that looked like this :
template<typename T, typename...Ts>
struct RemoveT
{
using type = /* a new type out of Ts that does not contain T */
}
Let's say that the marginal case RemoveT<int, int>
would be handled by returning void
(not handled in the code that follows). My initial design looks like this:
// --------------------------------------------------------------
// 1. A "way" of typedefing variadic number of types ------------
template<typename...Ts>
struct pack {
using type = Ts;
};
// --------------------------------------------------------------
// --------------------------------------------------------------
template<typename T, typename...Ts> struct RemoveT;
template<typename T, typename T1, typename...Ts>
struct RemoveT {
using type = typename pack<T1, typename RemoveT<T, Ts...>::type>::type;
};
template<typename T, typename T1>
struct RemoveT<T, T1> {
using type = T1;
};
template<typename T, typename...Ts>
struct RemoveT<T, T, Ts...> {
using type = typename RemoveT<Ts...>::type;
};
// --------------------------------------------------------------
Now I can't even begin to test this code because the pack
structure is not valid C++
Just in case this is helpfull for an answer, some other thoughs on solving it
pack
is not even useful at all. We could instead move around the RemoveT
structure, creating a new RemoveT
that only contains the types needed. The problem then transforms in extracting the types out of the structFor variadic types Ts
and a type T
: Can I create Us
out of Ts
ommiting T
?
The following provides a non-recursive and direct way to remove T
from Ts...
and, like Jarod42's solutions, yields a std::tuple<Us...>
but without the need to use typename ...::type
:
#include <tuple>
#include <type_traits>
template<typename...Ts>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));
template<typename T, typename...Ts>
using remove_t = tuple_cat_t<
typename std::conditional<
std::is_same<T, Ts>::value,
std::tuple<>,
std::tuple<Ts>
>::type...
>;
int main()
{
static_assert(std::is_same<
remove_t<int, int, char, int, float, int>,
std::tuple<char, float>
>::value, "Oops");
}