user3719401 user3719401 - 3 months ago 24
C++ Question

Tuple of sequence

I would like to store a sequence of classes into a tuple and declare this sequence as a member of another class:

template<size_t id> class Foo {};

template<size_t N>
class FooContainer
{
std::tuple<Foo<0>, Foo<1>, ..., Foo<N>> tup; // build this type at compile time ??
};


I tried this:

template<size_t N>
class FooContainer
{
template<size_t... id>
struct FoosImpl {
constexpr FoosImpl(std::index_sequence<id...>) {};
using type = std::tuple<Foo<id>...>;
};

template<size_t N, typename Indices = std::make_index_sequence<N>>
using Foos = decltype(FoosImpl(Indices())::type);

Foos<N> tup;
};


But this doesn't compiles. GCC complains:
error: missing template arguments before ‘(’ token using Foos = decltype(FoosImpl(Indices())::type);


I thought the compiler wouldn't need the template to be specified and that it would deduce the integer sequence from
Indices()
. But this doesn't seem to be the case.

Answer

Here is a possible way of doing what you want:

#include <tuple>

template<size_t id> class Foo {};

template <size_t... Idx>
std::tuple<Foo<Idx>...> get_foos(std::index_sequence<Idx...>);

template <size_t N>
using foo_tuple = decltype(get_foos(std::make_index_sequence<N>{}));

template<size_t N>
class FooContainer {
     foo_tuple<N> tup;
};

You cannot (currently) let the compiler deduce the class template parameters (as you would need with FoosImpl), but you can let it deduce the template parameters of a functions and use the return type.