I have run into a strange challenge trying to define a type based on an array while writing some library binding code.
Consider an enumeration like the following:
enum class MyTypes
{
UInt,
Int,
Float
}
With some type traits, I can convert a value of the enumeration into a type:
template <MyTypes Ty> struct typeify;
template <> struct typeify<MyTypes::UInt> { using type = unsigned int; };
template <> struct typeify<MyTypes::Int> { using type = int; };
template <> struct typeify<MyTypes::Float> { using type = float; };
template <MyTypes Ty> using typeify_t = typename typeify<Ty>::type;
To help with the binding, I also have this (because C++ doesn't have reflection):
inline static constexpr std::array KnownTypes
{
std::pair{"UInt", MyTypes::UInt},
std::pair{"Int", MyTypes::Int},
std::pair{"Float", MyTypes::Float}
};
From here, I want to define a std::variant based on my known types.
With 3 values, the obvious thing is to just write the variant like so:
std::variant<unsigned int, int, float>
But, in my situation, I have 50+ types. So, I would like a way to automatically generate the type definition for the std::variant from the array of KnownTypes and the typeify_t type trait.
I think I have gotten close with the following, but I have been stymied by not being able to give a variadic template parameter a default value:
template <template <typename T, T ... Idx> class temp = std::make_index_sequence<KnownTypes.size()>>
using AnyKnownType = std::variant<typeify_t<KnownTypes[Idx].second>, ...>;
Any problem in programming can be solved with another level of indirection (except too many levels of indirection).
Instead of directly creating a using expression template, create a function template declaration and use its return type in your using expression:
template <std::size_t... Is>
std::variant<typeify_t<KnownTypes[Is].second>...>
make_variant_type(std::index_sequence<Is...>);
using AnyKnownType = decltype(make_variant_type(std::make_index_sequence<KnownTypes.size()>()));
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With