At() with exceptions support is pretty much equivalent with a method returning an Option<T>. More precisely, it gives a superset of the functionality of returning Option<T>. If you declare the call site noexcept(), you should even get some compiler checking to make sure you handle the exception.
> If you declare the call site noexcept(), you should even get some compiler checking to make sure you handle the exception.
What compiler does it? At least g++ does not. It is not what specification dictates either.
I can't see how it is a superset either. If the library returns an Option, the calling code can process it as it please, including throwing an exception. On the other hand, if the library only indicates error by throwing an exception, it cannot work with the caller that is built with exceptions disabled.
Oops, you're right, the whole point of noexcept is to promise to the compiler that you know in practice exceptions can't happen, I got confused...
Otherwise, I should point out I explicitly said "at() with exception support enabled". It's also important the ability to disable exceptions is not a feature of C++, the C++ specs assume exceptions work (just like the Java or C# or Go specs). It is a feature of certain C++ implementations that they suport this mode, just like they support other non-standard features (compiler intrinsics, various #pragmas, etc).
Still even with exception support enabled I can't see what you can do with a function that throws that you cannot do with a function that returns maybe not Option<T>, but Result<T, E> in fewer lines of code.
Disabling exceptions is indeed not in the standard, probably because of Stroustrup's position (I respect many of his opinions, but cannot agree with this one) - but it's what every sane compiler, especially a one targeted at embedded systems, will support. Exceptions are designed for a controlled environment where a program terminating will return to somewhere that will maybe add a line to a logging system and restart it automatically. It only complicates things when terminating is an unacceptable scenario.
Yes, Result<T, E> should be equivalent in power to exceptions (the missing E part is why I was saying it's a superset of Option<T> functionality).
Regarding exceptions being more code, I very much don't agree. Even for embedded apps, the pattern of "if this fails, wind back up to some top level event loop" is quite common, and exceptions give it to you for free if you're also using RAII. In contrast, with Result<T, E> you have to write code at every level of the stack to handle it. Code which gets particularly ugly when you combine it with things like map() or filter().