On 4/23/13 3:43 PM, Gottlob Frege wrote:
On Tue, Apr 23, 2013 at 3:28 PM, Pierre T.
wrote: Le 23/04/2013 18:55, Gottlob Frege a écrit :
We can throw anything we want. I'm not sure it is a good idea, but you
can throw anything. It doesn't need to derive from std::expection, for example. You can throw an int. etc.
Of course, but I guess it's a bad practice ?
I'd agree with that.
What we did for optional<> is allow you to access the value in 2 ways:
optional<int> oi;
int x = oi.value(); // throws bad_optional_access int y = *oi; // undefined behaviour
Similar to vector [n] vs at(n).
We could use something similar in expected. But we must keep in mind that expected has a value and an error, is it clear that *expect return the value and not the error ?
Yes. It is called "expected" after all. You expect the value, not the error. And if there is an expect.is_valid() I expect it to be referring to whether the value is valid, not the error. Etc. It is not called "std::pair
", it is expected . IMO, at least.
It seems to me that if you're using this expected class, you're expecting an error, at least some times. Otherwise why wouldn't you just throw. FWIW I think the OP's idea of separating out the error handling code from the error site is misguided here. This isn't exceptional flow it's part of the normal expected behavior. If you're using it to parse user input for instance handling invalid input to me seems directly applicable to the task at hand even if it must be propagated a short ways to be handled. .
But I lean towards thinking that Error is rarely or never an exception - if it was, why use expected<> at all? Just throw the exception. I think of expected<> as being used in places where you don't want to use exceptions. ie if you have
expected
someFunction(); where someFunction() could *return* an exception, why not just
int someFunction(); // throws SomeException
So I think I'd prefer it always to wrap. ie assume that the Error is NOT an exception, and not meant to be thrown. The only time it is thrown is when someone (mistakenly? ie coder error) accesses the value via expect.value() and it throws bad_expected_access<Error>. Or "un_expected_access" :-)
Seems a lot like a code error to me. Might as well just throw std::logic_error if you're going to implement the anti-pattern. If you're going to specify what happens at all here you might as well std::terminate. Personally I would prefer leaving the behavior undefined.
What others think about this behavior and interface ?
Thanks for any comments. Pierre Talbot.
I'd definitely like to hear more from others. Maybe I'm not imagining some of the ways this is expected to be used.
I dislike expected's type not encoding what errors it the user should be
expected to handle.
In many ways it seems worse to me than returning a variant like
variant