5 ms·
A possible std::optional footgun is that an optional object can implicitly be converted to bool, returning optional has_value(). For optional objects that may h
by cpeterso 8y ago
A possible std::optional footgun is that an optional object can implicitly be converted to bool, returning optional has_value(). For optional objects that may hold value types that themselves can be used in a boolean context (like bool or a pointer value), then a programmer may confuse the implicit has_value() check with returning the real value().
std::optional<bool> opt(false);
assert(opt); // true even though *opt is false!
http://en.cppreference.com/w/cpp/utility/optional http://en.cppreference.com/w/cpp/utility/optional
- nneonneo 8y agoIs this really different than a pointer (or smart pointer) pointing to a false-y object? An optional isn’t implicitly convertible to its contained type - you have to use * or .value(), so it seems like there wouldn’t be much confusion.
- Retra 8y agoI suppose the difference would be that pointers-to-bool don't make a ton of sense in the first place, but using optional to wrap a boolean is a very reasonable thing to to.
- Matheus28 8y agoI don’t see it being reasonable at all. If you need more than two values, use an enum?
- deleted 8y ago[deleted]
- cpeterso 8y agoThat's a good point. If need a bool variable, there is a decent chance you will need more values later. In that case, an enum is more extensible and the names are more descriptive. Like the classic "Daily WTF?": enum Bool { True, False, FileNotFound }; http://thedailywtf.com/articles/What_Is_Truth_0x3f_ http://thedailywtf.com/articles/What_Is_Truth_0x3f_
- Koshkin 8y agoWell there you go: your 'True' resolves to 0 (and 'False' to 1). So, please don't do this. bool exists for a reason, and so does std::optional.
- Matheus28 8y agoI think you misunderstood my point (or exaggerated it a bit to make that reference). Regardless, Let me add my suggestion for those wanting to use std::optional<bool>: If a developer wants a yes/no/unknown type, an enum class is better suited for the job. This forces them to explicitly compare values instead of relying on an implicit boolean conversion.
- rocqua 8y agoIs the first number in a string even or odd? The function computing that is probably served really well by returning an optional bool.
- deleted 8y ago[deleted]
- avip 8y agoTernary logic (Yes/No/idk) is one of the most common use-cases for std::optional I've seen.
- Matheus28 8y agoThe vastly more common use-case I've seen is when you want to have an optional value, but don't want the heap allocation that comes with std::unique_ptr. std::optional is an useful wrapper because a simple "bool + object" would call constructors and all when that might be undesirable. IMO, ternary logic belongs as an enum class, to require developers to be explicit about what branches are taken for what values.
- Koshkin 8y agoheap allocation that comes with std::unique_ptr I think it may be worth mentioning that std::unique_ptr can be used to "manage" non-heap pointers as well.
- bobbyi_settv 8y agoAn optional containing a pointer seems pretty dubious. You would usually either just use a pointer and have null mean empty or use an optional containing the pointed-to type. An optional pointer is a weird tri state thing where you can have empty or a null pointer or a non-null pointer.
- Koshkin 8y agoSemantically though, not having a pointer value and having a value - even null - are two different things. For example, doing pointer arithmetic in the former case would be meaningless.
- netheril96 8y agoNull pointer arithmetic is undefined, so just as pointless as arithmetic on an empty optional pointer. Your example fails to prove that optional pointer has any valid use.
- deleted 8y ago[deleted]
- Koshkin 8y agoSure, my point might seem theoretical; to explain further, the difference is that when std::optional pointer is used correctly its behavior in the absence of a value is perfectly defined! Which is a good thing.
- klodolph 8y agoIt is generally dubious but you could easily end up with an optional containing a pointer if you're using templates. The type would predictably leak into parts of the code base calling the templated code. There are a bunch of other parts of the C++ code base that are the same way. The most notorious one I can think of is std::declval, which just makes no sense whatsoever unless it appears inside another template.
- hoppelhase 8y agoNow imagine you are using type inference using `auto` and you are refactoring some functions from returning `bool` to `optional<bool>`. Good luck with that.
- geezerjay 8y ago> returning `bool` to `optional<bool>`. In that case you need to pay attention to what you're doing. Semantically you'd be altering your code to convert a function that always returns a value into a function that maybe won't return it. How do you expect to replace a type with a wrapper that maybe won't wrap that type and still assume you won't need to check if a return value exists? That would be like replacing a reference with a pointer and then forgetting to check if the pointer is null. Making this mistake has nothing to do with luck and has everything to do with incompetence, and no language specs saves you from that.
- hoppelhase 8y agoOf course you have to check if the value exists. But you did not get my point. If the optional wouldn't be an implicit boolean, you'd see compile errors on the locations you forgot to change (even if you use type inference).
- deleted 8y ago[deleted]
- geezerjay 8y ago> A possible std::optional footgun is that an optional object can implicitly be converted to bool, That isn't true, as std::optional are explicitly converted to bool to signal whether the object stores a value. http://en.cppreference.com/w/cpp/utility/optional/operator_bool http://en.cppreference.com/w/cpp/utility/optional/operator_b...
- hoppelhase 8y agoDoes that prevent the usage shown in the blog post? std::optional<unsigned> opt = firstEvenNumberIn(text); if (opt)
- geezerjay 8y agoThat usage means "was the optional value set?" That's the whole point of an optional type, and there is absolutely no reason to prevent it.
- hoppelhase 8y agoThere is. See: https://news.ycombinator.com/item?id=17275784 https://news.ycombinator.com/item?id=17275784
- geezerjay 8y agoI've already explained why that argument makes no sense https://news.ycombinator.com/item?id=17276845 https://news.ycombinator.com/item?id=17276845
- hoppelhase 8y agoCould you elaborate more on why having the compiler tell us that we forgot to change something wouldn't be a good thing?