Replacing legacy C-style tagged unions with std::variant in Modern C++:
using Command = std::variant<PingCmd, AuthCmd, DataCmd>;
void ExecuteCommand(const Command& cmd) {
std::visit([](const auto& c) {
c.Run();
}, cmd);
}std::variant guarantees that non-trivial constructors and destructors of held types are properly invoked on reassignment, completely eliminating memory corruption bugs common in raw C union types.