I want to create an array where each element is (at runtime) calculated based on the type of each element of a Tuple. In practice I want to assign a runtime id to each type that exists in a tuple by calling getId on them.
template <Typename TupleType>
auto getIds() {
...
}
//So when calling
getIds<std::tuple<A, B, C>>()
//I want it to return a
std::array{ getId<A>(), getId<B>(), getId<C>() }.
And as mentioned above getId() is a runtime function, not constexpr.
I have tried many different solutions but I often end up with the problem of how to correctly unpack the tuple to parameter packs and then use index_sequence<> and make_index_sequence<>.
If you don't have to take a tuple the code can be simplified to
template<typename... Ts>
auto getIds()
{
return std::array{getId<Ts>()...};
}
If you need to handle the tuple instead then it gets a little more complicated since we create an index_sequence
to get each element type of the tuple. To do that we can leverage an immediately invoked lambda expression that we pass the index_sequence
to. That would give you
template <Typename TupleType>
auto getIds()
{
// no parameter name to avoid unused warning
return []<std::size_t... Is>(std::index_sequence<Is...>)
{
// make array like the first example geting the id for each element
return std::array{getId<std::tuple_element_t<Is, TupleType>>()...};
}(std::make_index_sequence<std::tuple_size_v<TupleType>>{});
// create index_sequence based on the size of the tuple and call the lambda to return the array
}