Reputation: 129
I have a typelist in form of std::tuple
struct A { struct data_type {}; };
struct B { struct data_type {}; };
struct C { struct data_type {}; };
struct D { struct data_type {}; };
//etc
using my_typelist = std::tuple<A, B, C, D>;
And I what define variable of tuple, containing inner types. Something like this
std::tuple<A::data_type, B::data_type, C::data_type, D::data_type> data;
But straightforward solution does not work (https://ideone.com/c8a2FE):
#include <tuple>
#include <iostream>
struct A { using data_type = int; };
struct B { using data_type = char; };
// error: template argument for template type parameter must be a type
template < typename... Ts >
using cvt_2_data = std::tuple< Ts::data... >;
void main()
{
using my_typelist = std::tuple<A, B>;
cvt_2_data<my_typelist> data;
std::cout
<< std::get<A::data_type>(data) << " "
<< std::get<B::data_type>(data) << std::endl;
}
I've also tried this, and more complicated approaches, but no such luck
std::tuple< (Ts::data)... >;
std::tuple< decltype(Ts)::data... >;
By the way, I need solution for C++17
Upvotes: 1
Views: 149
Reputation: 172924
It seems you want to specify std::tuple<A, B>
as template argument, and get the type std::tuple<A::data_type, B::data_type>
. You can do it with helper template and specialization. E.g.
template < typename... Ts >
struct cvt_2_data_struct;
template < typename... Ts >
struct cvt_2_data_struct<std::tuple<Ts...>> {
using type = std::tuple< typename Ts::data_type... >;
};
template < typename... Ts >
using cvt_2_data = typename cvt_2_data_struct<Ts...>::type;
BTW: Note the usage of typename
in typename Ts::data_type...
and typename cvt_2_data_struct<Ts...>::type
, it's used to tell that the dependent qualified name is type. See Where and why do I have to put the “template” and “typename” keywords?.
Upvotes: 3
Reputation: 58868
Try using partial specialization of a class/struct template:
template < typename T >
struct cvt_2_data_struct {};
template < typename... Ts >
struct cvt_2_data_struct<std::tuple< Ts... >> {
using type = std::tuple< typename Ts::data_type... >;
};
template < typename T >
using cvt_2_data = typename cvt_2_data_struct<T>::type;
Upvotes: 2