Performance aside, using variant has an added benefit of making illegal states unrepresentable. Optionals + an enum still allows users to either nullopt all the members, or have more than one member that is not nullopt.
As someone who does quite a bit of C++ recently: for most uses readability is king.
If you did want squeeze out the extra performance you could also do something where you store `std::variant<>` inside a struct and provide an API like this:
if (auto int_value = value.i()) {
// *int_value == your int
}
and expose a `std::variant<> &variant();` for use cases where you want the more complex/faster stuff.
Using variant as the storage type while providing a nice public accessor API makes sense given the huge difference in semantics between a struct containing optional fields and a variant.
Actually I was most interested in just how simple and readable I could make it. But I didn't say that in the post anywhere. Will add.