For me the important use case is pattern matching, which C++ doesn't yet have. Pattern matching really changes how you see the entire language.
Here is the first example I found on Google if that helps you understand.
std::variant<Fluid, LightItem, HeavyItem, FragileItem> package; std::visit(overload{ [](Fluid& ) { std::cout << "fluid\n"; }, [](LightItem& ) { std::cout << "light item\n"; }, [](HeavyItem& ) { std::cout << "heavy item\n"; }, [](FragileItem& ) { std::cout << "fragile\n"; } }, package);
match (state, pipe) { (State::None, Pipe::Ground) => { if inside { n += 1; } } (State::None, Pipe::Vert) => { inside = !inside; } (State::None, Pipe::Se) => { state = State::South; } (State::None, Pipe::Ne) => { state = State::North; } // Horizontal lines make no difference to anything (State::North | State::South, Pipe::Horiz) => {} // U-turns (State::South, Pipe::Sw) | (State::North, Pipe::Nw) => { state = State::None; } // Form a vertical line (State::South, Pipe::Nw) | (State::North, Pipe::Sw) => { inside = !inside; state = State::None; } _ => { panic!("Unexpected sequence {state:?} {pipe:?}"); } }
Guess what, the same syntax I gave supports exactly that as well.
For me the important use case is pattern matching, which C++ doesn't yet have. Pattern matching really changes how you see the entire language.