Не уверен, что именно вам нужно ... в любом случае ...
Конечно, вы не можете использовать значение const std::uint32_t id
для получения (find(id)
) типа(в качестве значения функции?), которую вы можете использовать в 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()
Если вам известно значение id
compile time (иначе ваш вопрос не имеет смысла) вы можете передать его (я предлагаю как std::size_t
) в качестве значения шаблона в std::integral_constant
template <std::size_t ID, uintypename T>
void add_item (std::integral_constant<std::size_t, ID>, T const item)
или лучше, я полагаю, непосредственно в качестве параметра шаблона, который выдолжен явно вызывать add_item()
.
В любом случае ... для карты типов, которую я предлагаю, прежде всего, ct_pair
(пара времени компиляции) между std::size_t
и типом
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>; };
вы можете создать ct_map
(карта времени компиляции), используя специализацию шаблона, мощность std::tuple_cat()
вместе с std::get_val()
и decltype()
следующим образом
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
using type_map = ct_map<ct_pair<2u, char>,
ct_pair<3u, int>,
ct_pair<5u, long>,
ct_pair<7u, long long>>;
и проверка static_assert()
станет чем-то
static_assert( std::is_same_v<type_map::find_type<5u>, long> );
Ниже приведен пример полной компиляции C ++ 17
#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> );
}