
Le 04/06/2017 à 22:40, Peter Dimov via Boost a écrit :
Gottlob Frege wrote:
Perhaps the heuristic could be, if the argument can be interpreted as > both a value and an error, the conversion is ambiguous, regardless of > which of the two is a better match. This will make
On Sun, Jun 4, 2017 at 12:35 PM, Peter Dimov via Boost the above return > ambiguous, which is probably as it should be.
I think I might agree with that. There will definitely be cases where expected<T,E> has T == int and E == int, and worse, sometimes those cases will be: - T is a template param, so you don't "see" that it is sometimes an int - E is a #define or platform-defined, etc, so it is only _sometimes_ an int
T == int, E == int is not a problem, because it will always be ambiguous. The thorny case is E == int, T == something convertible from int, such as double, long, unsigned.
Lets imagine ofr a moment that we allowed implicit conversion from convertible to T and convertible to E as far as both constructions are not possible. expected<double, unscoped_error> test() { return unscoped_other_error; // Compile Error as ambiguous } expected<double, unscoped_error> test() { return make_unexpected(unscoped_other_error); } Then if we want to be more explicit, then we can use wrappers that force us to be explicit: expected_ and unexpected_ are wrappers that are explicitly constructible from the wrapped type and provide explicit access to the value. expected<double, unexpected_<unscoped_error>> test() { return unexpected_{unscoped_other_error}; } Note that unexpect_<E> can not be implicltly convertible to E as otherwise we will have again an ambiguity. If we want also to be explicit on T expected<expected_<double>, unexpected_<unscoped_error>> test() { return expected_{3.0}; } The problem now is that we need to unwrap the wrapped types as the conversion is not implicit. My original design with an implicit unexpected_type was to avoid this unwrap operation, and define getter for unexpected_type<E> and also for the wrapped E. Given an expected that has the implicit constructors, we can build another expected_expl that has his constructors explicit and provide unwrapping operation. The same can be achieve from a expected that has explicit constructors, we can define a expected_impl that has his constructors implicit. Do we need both approaches? I don't know.. Vicente