5 ms·
> It's also incredibly unsafe and why generics aren't enough. C++, Java, and so on have had generics for ages and with types like the one above, null pointer ex
by jcelerier 6y ago
> It's also incredibly unsafe and why generics aren't enough. C++, Java, and so on have had generics for ages and with types like the one above, null pointer exceptions are incredibly common.
uh, you'd never get a null-pointer exception in C++ given the type that OP mentioned. Value types in C++ cannot be null (and most things are value types by a large margin).
- nine_k 6y agoWell, T can be a pointer / reference here.
- jcelerier 6y agoThat wouldn't change anything to Result<T>'s implicit safety properties. "safe + unsafe == unsafe" - to have a meaningful discussion we should focus on the safe part, else it's always possible to bring up the argument of "but you can do ((char*)&whatever)[123] = 0x66;"
- sedatk 6y agoYou can also constrain a generic type only to value types in C#: class Result<T> where T: struct { ... } In that case it can't be null with C# either.
- AaronFriel 6y agoThen you can't construct it unless it's successful, no? A Result<T> that can only contain successful values doesn't seem very useful
- sedatk 6y agoYou can, it's possible to address "missing values" with a default construct. Example: int x = default; // x becomes zero T x = default; // x becomes whatever the default value for struct is
- AaronFriel 6y agoThen we're back to accessing that value being an enormous footgun, yes?
- loopz 6y agoInstead you can have undefined behaviour in C++. Don't think get;set is C++, though it breaks encapsulation.
- AaronFriel 6y agoThen you can't construct it unless it's successful, no? A Result<T> that can only contain successful values doesn't seem very useful
- joshuamorton 6y agoNo, you just are forced to use methods like foo.UnwrapOr(default_value) to get the Result. Or depending on the language, you get a compile error if you don't handle both possible values of the Result enum in a switch statement or if/else clause. See for example https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default https://doc.rust-lang.org/std/result/enum.Result.html#method... in rust, https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElse-T- https://docs.oracle.com/javase/8/docs/api/java/util/Optional... in Java, and https://en.cppreference.com/w/cpp/utility/optional/value_or https://en.cppreference.com/w/cpp/utility/optional/value_or in C++.
- AaronFriel 6y agoWho are you replying to? Is any of your elaboration related to this result type? class Result<T> { bool IsSuccess {get; set;} string Message {get; set;} T Data {get; set;} }
- joshuamorton 6y agoAh you're quite correct.
- grandmczeb 6y agoYes you can? The equivalent type in C++ is std::expected[1] which doesn't even contain a pointer that could be dereferenced (unless T is a pointer obviously). [1] unfortunately not standardized yet https://github.com/TartanLlama/expected https://github.com/TartanLlama/expected
- AaronFriel 6y agoWho are you replying to? Is it in any way related to the original comment I replied to and this type? class Result<T> { bool IsSuccess {get; set;} string Message {get; set;} T Data {get; set;} }
- temac 6y ago> Value types in C++ cannot be null They can just not exist. And C++ being C++, dereferencing an empty std::optional is UB. In practice this particular UB often leads to way worse consequences than more "conventional" null-pointer derefs.
- gpderetta 6y agoThen write your own optional that always checks on dereference or toggle whatever compilation flag enables checking in the standard library you are using.