What about providing no default constructor? There are two valid choices so
why surprise half the users?
Yes, it makes it a bit harder to use in arrays, but how often would it need
to be stored in arrays anyways.
Jonathan
On May 24, 2017 10:38 PM, "Niall Douglas via Boost"
4. Function r.empty() is implemented as `r.has_error() && !error()`.
So you are requesting that error is explicitly convertible to bool. This could work for outcome and result as the errors provide it but not for expected
. I don't believe the library should make use of this bool conversion. Even the opposite. I will add a pre-condition that the Error value if convertible to bool is equal to false (this can be also cheched at run-time). std::error_code does not have a constexpr constructor, and does not have a constexpr .value() nor explicit operator bool(). Very unfortunate. It also precludes doing a generic check that a default constructed E tests to boolean false, so you will need that generic check plus a special override for std::error_code and subclasses of std::error_code.
5. Framework requires that type E in `expected
` is default-constructible, and its default-constructed value represents no error condition (already the case for exception_ptr, error_code). This is something that the library cannot check without adding more constraints. The interpretation that the user does of each one of the values of E is up to him. I would agree.
A null error_code has the convention of "no error here", but as I've explained in previous discussion, because of the C++ standard requiring system_category with a code of 0 for default construction, it rules out anyone *portably* treating a null error_code as "no error here".
Until the C++ standard gets fixed, we cannot assume this of the null error code any more than the Filesystem TS does (which it does, incidentally, and it should not).
If the user uses values of Error that doesn't mean an error, you have a tri-state. IMO, the use error_code{} or exception_ptr{} with outcome or expected is an ERROR.
I disagree. That is on the end user to decide, not us.
At the end I'm not sure result<T> or expected<T> should have a default constructor. Note that we want variables initialized at the declaration and the default construction of these types is always artificial.
I too felt this, which was one of my rationales for the formal empty state. Completely eliminating the default constructor altogether does seem attractive ... but it would be a usability pain for end users.
Concerning the default construction, I'm inclined to think that in this cases the best is to don't initialize as a T or as E. Note that this doesn't mean to add an additional state. The result of default construction is just a partial initialized state that needs either to be assigned or destructed, as if we had do a move. Trying to use has_value on this state will be UB.
Ah, more UB. Yay.
The advantage is that IMO, is that we don't spend more time than we need. Not all types should have a well formed object as default value (See e.g. chrono::duration, Date).
If the formal empty state is to be removed, then either you default construct T, or E, or you go the UB route. I still find the formal empty state the most attractive, but I recognise no one agrees with me.
Niall
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost