There are two things being discussed in this thread.
1. The first, my original point was that a high quality type system enforces correctness by more than just having generics. There's no proper way in C++ to create this class and make a sum type - there's no pattern matching or type narrowing like can be done in languages with more interesting type systems and language facilities. Generics is just a first step to a much more interesting, safer way of writing code.
2. The second, my replies to folks who have corrected me, and I'll borrow your little paraphrase here:
> [Me]: "C++, Java, and so on have had generics for ages and with types like the one above, null pointer exceptions are incredibly common."
>
> jcelerier: "you'd never get a null-pointer exception in C++ given the type that OP mentioned."
>
> [Me]: "Then you can't construct it unless it's successful, no?"
I think this is exactly correct still. If it's impossible to create an instance of Result<T> without... well, a successful result, you may as well just typedef Result<T> to T, right? If it can't store the "failure" case, it's totally uninteresting.
If it _can_ store the failure case, making it safe in C++ is fairly challenging and I dare say it will be a little longer and a little less safe than a Result I can write in a few lines of TypeScript, Scala, Rust, an ML or Haskell derivative, and so on.
Now, I'd love to be proven wrong, I haven't written C++ for a while so the standard may have changed, but is there a way to write a proper enum and pattern match on the value?
It looks like this std::expected thing is neat, but can a _regular person_ write it in their own code and expect it to be safe? I can say with certainty that I can do that for the languages I listed above and in fewer than 10 lines of code.
The C++ answer to that is, well, this:
https://github.com/TartanLlama/expected/blob/master/include/...
I don't think it's a comparison.