Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a type list to expand into a tuple?

Tags:

c++

c++11

c++14

I am trying to create a class that has a tuple of all the types that are passed to it. I want it to take a type list as a template parameter, and use the classes within that list as the classes an internal tuple will contain. Currently, I have something like this, which doesn't actually compile.

template<class ... T>
struct ComponentList {};

template<ComponentList<typename ...T> >
class ComponentManager{
    std::tuple<T...> components;
};

The reason I want to have ComponentList be its own type is because I want to also pass in other type lists later. Is this possible? If not, what would be an alternative that will work?

like image 411
user975989 Avatar asked Feb 04 '16 01:02

user975989


People also ask

How do I turn a list into a tuple?

1) Using tuple() builtin function tuple () function can take any iterable as an argument and convert it into a tuple object. As you wish to convert a python list to a tuple, you can pass the entire list as a parameter within the tuple() function, and it will return the tuple data type as an output.

Can you extend a list with a tuple in Python?

To append tuple to the list, we can use the list extend() method. First, define a tuple and list and then append tuple to list using extend() method.

Can we create tuple of list?

we can create a list of tuples using list and tuples directly.


1 Answers

You can add a template to rebind the parameters from your type-level list into std::tuple:

template<class A, template<class...> class B>
struct rebind_;

template<template<class...> class A, class... T, template<class...> class B>
struct rebind_<A<T...>, B> {
    using type = B<T...>;
};

template<class A, template<class...> class B>
using rebind = typename rebind_<A, B>::type;

Then use it like so:

template<class... T>
struct ComponentList {};

template<class List>
struct ComponentManager {
    rebind<List, std::tuple> components;
};

int main() {
    using List = ComponentList<int, char, long>;
    ComponentManager<List> manager;
    std::cout << std::get<0>(manager.components) << '\n';
}

I guess if you want to enforce that the original type is ComponentList, you can use enable_if and is_instantiation_of:

template<class List,
    typename = std::enable_if<is_instantiation_of<List, ComponentList>::value>::type>
struct ComponentManager {
    rebind<List, std::tuple> components;
};
like image 78
Jon Purdy Avatar answered Nov 02 '22 10:11

Jon Purdy