I'm given a std::variant
of several types. I would like to write a trait that gives another std::variant
of the pointer of the types of the first.
using MyVariant = std::variant<int, float>;
using MyVariantOfPointers = pointer_of_v<MyVariant>;
such that MyVariantOfPointer
is std::variant<int*, float*>
.
I tried to play with std::variant_size_v
and std::variant_alternative_t
but I do not know how to build the new type recursively.
You can use partial specialization to write a trait to solve this.
// General case
template<class T>
struct VariantToPtrVariant;
// Partial specialization when used with std::variant
// Extracts the template arguments from the `std::variant` and
// produces a new `std::variant` with those types, with an added `*`
template<class ... T>
struct VariantToPtrVariant<std::variant<T...>> {
using type = std::variant<T*...>;
};
// Helper variable template
template<class T>
using VariantToPtrVariant_t = typename VariantToPtrVariant<T>::type;
Usage :
using MyVariant = std::variant<int, float>;
using MyVariantOfPointers = VariantToPtrVariant_t<MyVariant>;
Complete example (https://godbolt.org/z/qaTxo4nzc) :
#include <type_traits>
#include <variant>
template<class T>
struct VariantToPtrVariant;
template<class ... T>
struct VariantToPtrVariant<std::variant<T...>> {
using type = std::variant<T*...>;
};
template<class T>
using VariantToPtrVariant_t = typename VariantToPtrVariant<T>::type;
using MyVariant = std::variant<int, float>;
using MyVariantOfPointers = VariantToPtrVariant_t<MyVariant>;
static_assert(std::is_same_v<MyVariantOfPointers, std::variant<int*, float*>>);