Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Rust's language-level support for pattern matching (including exhaustiveness checking) is very nice. Most languages with sum types have this feature. It's hard to imagine one without the other. I haven't used `std::variant` much, but I remember finding it unergonomic. Real-world C++ code uses `std::variant` way less often than Rust/functional code uses sum types. Probably, for that reason

UPDATE: also, some advantages coming from the interaction of enums with other Rust language features:

- Because Rust doesn't have a stable ABI, the compiler is free to agressively optimize the layout of enums. The size of an enum is often equal to (rather than greater than) the size of the largest variant, if the variant has some "impossible" bit values (like null pointers and non-UTF8 chars) that can be used for storing the tag.

- Because Rust traits can (and must) be implemented outside of the type definition, you can implement a trait directly for an enum and then use that enum as a polymorhpic "trait object". In C++, if you want to polymorphically use an `std::variant` as a subclass of something, you need to define an ackward wrapper class that inherits from the parent.



I agree, the lack of pattern matching is a bummer. You should retry std::variant with the lambda overload trick though. It's kind of okay in terms of syntax.

    using MyDiscreminatedUnion = std::variant<MyType1, MyType2, MyType3>;

    MyDiscreminatedUnion var = MyType2{};

    std::visit(overload {
        [](MyType1 t1) {...},
        [](MyType2 t2) {...},
        [](auto t) {...},
   }, var);


You can even do better with something like:

namespace StlHelpers {

template<class... Ts> struct overload : Ts... { using Ts::operator()...; };

template<class... Ts> overload(Ts...) -> overload<Ts...>;

template<class var_t, class... Func> auto visit(var_t & variant, Func &&... funcs)

{

    return std::visit(overload{ funcs... }, variant);
}

}

And then

StlHelpers::visit(var,

    [](MyType1 t1) {...},

    [](MyType2 t2) {...},

    [](auto t) {...}
);




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: