Is there a utility in the standard library to get the index of a given type in std::variant
? Or should I make one for myself? That is, I want to get the index of B
in std::variant<A, B, C>
and have that return 1
.
There is std::variant_alternative
for the opposite operation. Of course, there could be many same types on std::variant
's list, so this operation is not a bijection, but it isn't a problem for me (I can have first occurrence of type on list, or unique types on std::variant
list).
Update a few years later: My answer here may be a cool answer, but this is the correct one. That is how I would solve this problem today.
We could take advantage of the fact that index()
almost already does the right thing.
We can't arbitrarily create instances of various types - we wouldn't know how to do it, and arbitrary types might not be literal types. But we can create instances of specific types that we know about:
template <typename> struct tag { }; // <== this one IS literal
template <typename T, typename V>
struct get_index;
template <typename T, typename... Ts>
struct get_index<T, std::variant<Ts...>>
: std::integral_constant<size_t, std::variant<tag<Ts>...>(tag<T>()).index()>
{ };
That is, to find the index of B
in variant<A, B, C>
we construct a variant<tag<A>, tag<B>, tag<C>>
with a tag<B>
and find its index.
This only works with distinct types.
I found this answer for tuple and slightly modificated it:
template<typename VariantType, typename T, std::size_t index = 0>
constexpr std::size_t variant_index() {
static_assert(std::variant_size_v<VariantType> > index, "Type not found in variant");
if constexpr (index == std::variant_size_v<VariantType>) {
return index;
} else if constexpr (std::is_same_v<std::variant_alternative_t<index, VariantType>, T>) {
return index;
} else {
return variant_index<VariantType, T, index + 1>();
}
}
It works for me, but now I'm curious how to do it in old way without constexpr if, as a structure.
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