c++stdtupleparameter-pack

Creating a std::array of templated functions results based on the types of a tuples elements


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<>.


Solution

  • 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
    }