I am replying to you and its pretty obviously related to your comment.
You: "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."
You: "Then you can't construct it unless it's successful, no?"
Me: "The equivalent type in C++ [to what the OP mentioned] is std::expected". It is not possible to get a null-pointer exception with this type and yet you can construct it.
It sounds quite a lot like you took the type the OP posted and changed it in your reply to a different type that isn't standardized yet, do I have that right?
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 linked link has a ton of things that are "quality-of-life" things. For instance comparing two Result values efficiently (you don't want to compare two Result<T> bitwise, and you don't want the "is_valid" flag to be first in the structure layout to fallback on the automatic default of lexical order as that would sometimes waste a few bytes, but you want the "is_valid" flag to be the first thing being compared for instance. Do you know of a language that would do that automatically ?).
It also supports back to C++11 and GCC4.9 with various fixes for some specific compiler versions's bugs, supports being used with -fno-exceptions (so a separate language than ISO C++) - sure, today's languages can do better in terms of prettiness, but so would a pure-C++20 solution that only needs to work with a single implementation.
If you are ready to forfeit some amount of performance, for instance because you don't care that the value of your Result will be copied instead of moved when used in a temporary chain (e.g. `int x = operation_that_gets_a_result().or_else([] (auto&& error) { return whatever; });` 3/4 of the code can go away (and things will still likely be faster than most other languages).
You: "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."
You: "Then you can't construct it unless it's successful, no?"
Me: "The equivalent type in C++ [to what the OP mentioned] is std::expected". It is not possible to get a null-pointer exception with this type and yet you can construct it.