13 Sep
2018
13 Sep
'18
8:14 a.m.
> Well, throwing an exception is not the only reasonable choice here. For > instance, some people use the STL compiled in -no-exceptions mode. In such > case, in any place where normally an exception would be thrown, function > `abort()` is called instead. For uniformity, these users might expect > Outcome to also call `abort()`. `abort()` is not an UB: it is predictable, > and drastic as it is, it can still be considered as means of handling > errors. For instance in a video game: if it occasionally crashes, it is > acceptable. Then maybe define the policy function for creating an exception like this: - if it is not defined: value() cannot be called - if it has void return type then call terminate/abort (maybe require a trait instead?) - if it has a non-void return type, throw this > The "value() always wide, assume_value() always narrow" solution appears > very clear and easy to explain, however it might turn to be not acceptable > for social reasons. Name `value()` sounds attractive and users want to use > it by default: both the users that compile with no-exceptions, and the > users who wan to us exceptions and the `fun().value()` idiom. IMO reasoning about code is more important than brevity. As already mentioned: When doing a code review you may see: `if(result) result.value().use();` You may conclude that this is wrong/superflous until you learn that the policy for this result type defined anywhere anyhow allows this. Then you see a non-guarded `result.value().use();` and may (wrongly) conclude it is correct as it throws, but it doesn't. In the end the solution is very easy: "users that compile with no-exception" use a terminate-on-valueless-value()-policy and the `if(result) result.value().use();` usage. Note that the `value()` will have the same valueless-check as done by the `if(result)` and will then be eliminated by the compiler. So they ALWAYS have correct behaviour (forgetting the if will terminate) and the nice looking code. See also https://blog.fefe.de/?ts=a5686503 for why omitting the range check in string/vector operator[] was/is a mistake.