Is there a way to strip a std::tuple<T...>
in order to get it back to T...
?
Example
Suppose vct<T...>
is a pre-existing variadic class template,
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = vct< strip<U> >; // should be same as X
Notes
I know about std::tuple_element, but I need all the elements, in a form that is usable as T...
For reference, I have found this question, which is similar, but my needs are somewhat simpler (so I hope there is a simpler solution): all I need is the list of types that are in the tuple
- I don't care about the actual values of a tuple
instance.
No, this is not possible. Argument packs are the result of type deduction, and they can't be produced in other contexts.
You could do something similar to what you're asking for this way:
template<template<typename...> class T, typename>
struct instantiate_with_arg_pack { };
template<template<typename...> class T, typename... Ts>
struct instantiate_with_arg_pack<T, std::tuple<Ts...>>
{
using type = T<Ts...>;
};
template<typename... Ts>
struct vct { };
int main()
{
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = instantiate_with_arg_pack<vct, U>::type;
}
Actually, you don't need to hold the argument pack in a tuple: any variadic class template is OK:
template<template<typename...> class T, typename>
struct instantiate_with_arg_pack { };
template<
template<typename...> class T,
template<typename...> class U, // <===
typename... Ts
>
struct instantiate_with_arg_pack<T, U<Ts...>>
// ^^^^^^^^
{
using type = T<Ts...>;
};
template<typename... Ts>
struct vct { };
int main()
{
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = instantiate_with_arg_pack<vct, X>::type;
// ^
// Won't fire
static_assert(
std::is_same<Y, vct<int,char,std::string>>::value,
"Error!");
}
And here is a live example.