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.
template<typename>
struct strip;
template<typename ...T>
struct strip<std::tuple<T...>>
{
using type = vct<T...>;
};
then use this as:
using Y = strip<U>::type;
Now Y
is same as X
.
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.
You can not directly "return" a parameter pack, so what you need is something like this:
template< typename... Ts >
struct vct
{ ... };
template< typename T >
struct make_vct;
template< typename... Ts >
struct make_vct< std::tuple< Ts... > >
{
typedef vct< Ts... > type;
};
and use
using Y = make_vct< U >::type;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With