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

From the article:

> it’s completely bonkers to expect the average user to build an overloaded callable object with recursive templates just to see if the thing they’re looking at holds an int or a string.

You don't have to: http://en.cppreference.com/w/cpp/utility/variant/holds_alter... (and http://en.cppreference.com/w/cpp/utility/variant/get to access the value).



And now you get neither exhaustive checking nor type-safe unwrapping, at this point is there really a point to variants? You may as well be using the old enum+union.

(get_if at least nets you type-safe unwrapping similar to `if let` in Swift or Rust, though it returns a pointer rather than a reference)


You either want exhaustive checking or "just [want] to see if the thing they’re looking at holds an int or a string". OPs comment was about the latter and holds_alternative and get accomplishes that.

FWIW, std::get is type-safe in that you cannot specify a type outside of the variant types. It's safe at runtime in that it will throw std::bad_variant_access if the active object doesn't match the type.

And because of this, you think we may as well use enum+union? Even if you only plan on manually type switching on a variant, std::variant saves you from a lot of boilerplate.


Not the same as what the article is trying to accomplish, which is an exhaustive match (i.e., any unmatched value is guaranteed to fail at compile time).

For example, consider a parser that matches on tokens. If you add a new token, the match should fail, because you want to guarantee, at compile-time, that every possible case is handled.

This is one reason that the lack of sum types in Go is so painful, to the point that someone wrote a special library for it [1].

[1] https://github.com/BurntSushi/go-sumtype


I'm familiar with the approach from other languages that the article tries to import into C++ before concluding that the designers should watch out for language envy (incidentally, Stroustrup wrote a paper on efficient type matches: http://stroustrup.com/OpenPatternMatching.pdf ). The author picks a particular approach and then shows that the approach isn't satisfactory. But the author did not go back to try another approach.

If the visitor approach is acceptable but has_alternative is not, get<> also accepts index values (as numeric template parameters, e.g., get<0>(v), get<1>(v), etc.) and variant has a method called index() to give a numeric value saying what the current type is. This is easy enough to use in a switch statement:

    std::variant<int, double, std::string> v;
    ...
    switch (v.index()) {
        case 0:
            std::printf("%d\n", std::get<0>(v));
            break;
        case 1:
            std::printf("%f\n", std::get<1>(v));
            break;
        case 2:
            std::puts(std::get<2>(v).c_str());
            break;
    }
In this case you can add a default: branch and throw an error for unhandled types, or you can hope that the compiler issues a warning about a missing case (index is constexpr, so it's possible for the compiler to know that you've missed something). It's not as good as a compile error, but it might be good enough.


While I think it's just a honest overlook by the author (C++17 is just really new), I still think it's funny that a huge portion of the entire article and by extension the argument against variants is rendered moot by RTFM.


I think the author's goal was quite obviously to have strong sum types with compile-time safety and branch resolution. In other words, to make it impossible to use the value stored in the variant in a manner inconsistent with its type because doing otherwise is a compile-time error.

The above parts of the standard library don't help in achieving this goal.


[flagged]


Please don't post snarky, unsubstantive comments regardless of how wrong other people are about programming languages.

https://news.ycombinator.com/newsguidelines.html




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

Search: