std-make
std-make copied to clipboard
expected (rev9): Omissions and mistakes
Under Section 1.6
-
template<class U, class G> explicit(see below) constexpr expected(const expected<U, G>& rhs): Are the constraints involvingEandGstill applicable whenTandUare cvvoid? -
template<class U, class G> explicit(see below) constexpr expected(expected<U, G>&& rhs): Are the constraints involvingEandGstill applicable whenTandUare cvvoid? -
template<class... Args> constexpr explicit expected(unexpect_t, Args&&... args);: Should be "with the argumentsin_place, std::forward<Args>(args)...." -
template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);: Should be "with the argumentsin_place, il, std::forward<Args>(args)...."
Under Section 1.8
-
expected& operator=(const expected& rhs) noexcept(see below);: noexcept specification does not match the one in the class synopsis. -
expected& operator=(expected&& rhs) noexcept(see below);- Missing std::move, should be
move constructs an
unexpected_type<E> tmpfromunexpected(std::move(this->error()))(which can’t throw as E is nothrow-move-constructible)-
For
!bool(*this) && bool(rhs), missing "and sethas_valtotrue" -
Constraint for when
Tis cv void should beis_move_constructible_v<E>istrueandis_move_assignable_v<E>istrue. -
Constraint for when
Tis not cv void should be (determined by following the logic in the table):is_move_constructible_v<T> && is_move_assignable_v<T> && is_move_constructible_v<E> && is_move_assignable_v<E> && (is_nothrow_move_constructible_v<E> || is_nothrow_move_constructible_v<T>) -
The expression inside noexcept should be equivalent to:
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
-
template<class G = E> expected<T, E>& operator=(const unexpected<G>& e);: Table is inverted -
expected<T, E>& operator=(const unexpected<G>& e);andexpected<T, E>& operator=(unexpected<G>&& e);-
Should be
e.value()instead ofe.error(). -
Temporary
unexpected<E>should be created fromunexpected<G>before destroyingvalto ensure strong exception guarantee.
-
-
expected<T, E>& operator=(unexpected<G>&& e);, for!bool(*this): Missing std::move, should be "move assignunexpected(std::move(e).value())to unex". -
template<class U = T> expected<T, E>& operator=(U&& v);: Missing std::move, should be
move constructs an
unexpected<E> tmpfromunexpected(std::move(this->error()))(which can’t throw as E is nothrow-move-constructible)
-
Why are there no assignment operator overloads taking
expected<U, G>? There are after all assignment operator overloads for std::optional takingstd::optional<U>. -
template<class... Args> T& emplace(Args&&... args);: By following the logic under Effects, the constraint should beis_constructible_v<T, Args...> && (is_nothrow_constructible_v<T, Args...> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>). Upon exception, one or more arguments may be left in a post-moved state, so the "nothing changes" remark is not completely accurate. -
template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);: By following the logic under Effects, the constraint should beis_constructible_v<T, L, Args...> && (is_nothrow_constructible_v<T, L, Args...> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>)whereLisstd::initializer_list<U>. Upon exception, one or more arguments may be left in a post-moved state, so the "nothing changes" remark is not completely accurate.
Under Section 1.9
-
Constraints should be
is_nothrow_move_constructible_v, notis_move_constructible_v. -
In table, for
bool(*this) && !bool(rhs)and is cv void, should beunexpected(std::move(rhs.error()))(missing.error())
Under Section 1.10
-
constexpr T&& expected::value() &&andconstexpr const T&& expected::value() const&&: Should they throwbad_expected_access(std::move(*this).error())instead, in order to allow move-only error types? -
value_or: Behavior and/or constraints need to be clarified whenTisvoid. Does it ignore the argument and do nothing, or is it disabled entirely?
Under Section 1.12
-
operator!=: Should be "expression*x != vis well-formed. -
operator!=: Should be "Returns:bool(x) ? *x != v : true;. Ifxholds an error, than is it unequal to any valuev. Otherwise,!( x != v)would not be the same asx == v.
Under Section 1.14
- Constraints don't match those for member swap.
Under Section 1.17.1
-
Should be
Errin constraints, instead ofU. -
template<class Err> constexpr explicit unexpected(Err&& e): Should beunexpect_tin constraints, notunexpected.