Not sure about what do you exactly want... anyway...
Surely you can't use a const std::uint32_t id value to obtain (find(id)) a type (as a value of a function?) that you can use in a static_assert()
template <typename T>
void add_item (std::uint32_t const id, T const item)
// ................................^^ the value id is unusable in a static_assert()
If you know the value of id compile time (otherwise your question do not make sense) you can pass it (I suggest as std::size_t) as template value in a std::integral_constant
template <std::size_t ID, uintypename T>
void add_item (std::integral_constant<std::size_t, ID>, T const item)
or better, I suppose, directly as template parameter that you have to explicit calling add_item().
Anyway... for the type map I propose, first of all, a ct_pair (compile time pair) between a std::size_t and a type
template <std::size_t, typename>
struct ct_pair
{ };
Given also a couple of helper structs as follows
template <std::size_t, std::size_t, typename>
struct get_tuple
{ using type = std::tuple<>; };
template <std::size_t I, typename T>
struct get_tuple<I, I, T>
{ using type = std::tuple<T>; };
you can create a ct_map (compile time map), using template specialization, the power of std::tuple_cat() together with std::get_val() and decltype() as follows
template <typename ...>
struct ct_map;
template <std::size_t ... Is, typename ... Ts>
struct ct_map<ct_pair<Is, Ts>...>
{
template <std::size_t I>
static constexpr auto find_type_func ()
-> decltype( std::get<0>( std::tuple_cat(
std::declval<typename get_tuple<I, Is, Ts>::type>()...)) );
template <std::size_t I>
using find_type
= std::remove_reference_t<decltype( find_type_func<I>() )>;
};
To register the elements on a map you have to define a using
using type_map = ct_map<ct_pair<2u, char>,
ct_pair<3u, int>,
ct_pair<5u, long>,
ct_pair<7u, long long>>;
and the static_assert() check become something as follows
static_assert( std::is_same_v<type_map::find_type<5u>, long> );
The following is a full compiling C++17 example
#include <tuple>
#include <iostream>
#include <type_traits>
template <std::size_t, typename>
struct ct_pair
{ };
template <std::size_t, std::size_t, typename>
struct get_tuple
{ using type = std::tuple<>; };
template <std::size_t I, typename T>
struct get_tuple<I, I, T>
{ using type = std::tuple<T>; };
template <typename ...>
struct ct_map;
template <std::size_t ... Is, typename ... Ts>
struct ct_map<ct_pair<Is, Ts>...>
{
template <std::size_t I>
static constexpr auto find_type_func ()
-> decltype( std::get<0>( std::tuple_cat(
std::declval<typename get_tuple<I, Is, Ts>::type>()...)) );
template <std::size_t I>
using find_type
= std::remove_reference_t<decltype( find_type_func<I>() )>;
};
using type_map = ct_map<ct_pair<2u, char>,
ct_pair<3u, int>,
ct_pair<5u, long>,
ct_pair<7u, long long>>;
int main()
{
static_assert( std::is_same_v<type_map::find_type<5u>, long> );
}