On 23/01/2018 03:53, Niall Douglas wrote:
My recommendation would be not to provide comparison operators if either `T` or `EC` does not provide them.
Agreed. Logged to https://github.com/ned14/outcome/issues/107
I assume this would be individually for each case? There is still benefit in providing operator==(EC) even if T does not provide operator==, eg. for the construct: if (outcome == make_error_code(xxx)) (not sure if this is the exact spelling, but it's something like this) Especially in generic code templated on T. The alternative is much more wordy and not really any clearer. There are also some benefits in retaining the current 'return false' behavior for error comparisons (only), again for generic code that wants to test against several possible heterogeneous specific errors. On the other hand, it probably is safest to make this a compile error to catch the case when someone changes the EC of a method and require the callers to update their checks.
The trick with catch-reswap-rethrow assumes that `T` is more likely to throw while swapping/moving than `EC`, but it might be quite the opposite. Also, it is possible that while reswapping, another exception will be thrown. In general, you cannot guarantee the roll-back, so maybe it would be cleaner for everyone if you just declared that upon throw from swap, one cannot rely on the state of `result`: it should be reset or destroyed.
So, don't bother attempting to restore a valid state at all?
Does everybody else agree?
While it's true that EC could throw on swap, it's probably not very likely given that EC is most likely to be either error_code (or moral equivalent) or a simple enum/int. So that should be reasonably safe in the majority of cases. Swapping back noexcept(false) T might be more problematic; successful swap out is not a guarantee of successful swap back.