Convert std :: variant to another std :: variant with a super-set of types

I have a std::variant that I would like to convert to another std::variant , which has a super-set of its types. Is there a way to do this than it allows me to simply assign one to another?

 template <typename ToVariant, typename FromVariant> ToVariant ConvertVariant(const FromVariant& from) { ToVariant to = std::visit([](auto&& arg) -> ToVariant {return arg ; }, from); return to; } int main() { std::variant<int , double> a; a = 5; std::variant <std::string, double, int> b; b = ConvertVariant<decltype(b),decltype(a)>(a); return 0; } 

I would just like to write b = a to do the conversion, and not go through this complicated casting setting. Without polluting the std .

Edit: just writing b = a gives the following error:

 error C2679: binary '=': no operator found which takes a right-hand operand of type 'std::variant<int,double>' (or there is no acceptable conversion) note: while trying to match the argument list '(std::variant<std::string,int,double>, std::variant<int,double>)' 
+5
source share
2 answers

This is the implementation of the second Yakk variant:

 template <class... Args> struct variant_cast_proxy { std::variant<Args...> v; template <class... ToArgs> operator std::variant<ToArgs...>() const { return std::visit([](auto&& arg) -> std::variant<ToArgs...> { return arg ; }, v); } }; template <class... Args> auto variant_cast(const std::variant<Args...>& v) -> variant_cast_proxy<Args...> { return {v}; } 

You might want to fine-tune it to forward semantics.

And as you can see, its use is simple:

 std::variant<int, char> v1 = 24; std::variant<int, char, bool> v2; v2 = variant_cast(v1); 
+3
source

Options:

  • Write your own variant type, possibly inheriting from std::variant , which implements operator= and builds the way you want. Some work needs to be done because variant constructors may do SFINAE tricks that may not work properly with your variant type; for this purpose you want to do some SFINAE forwarding for the base version yourself, and not a bare using declaration.

  • Write a better ConvertVariant that doesn't require specifying source / destination types. You will return a template-template-converter that contains the original version, which has an operator std::variant<Ts...>()&& that calls something very similar to your ConvertVariant .

0
source

Source: https://habr.com/ru/post/1273243/


All Articles