Under Section 1.6
-
template<class U, class G> explicit(see below) constexpr expected(const expected<U, G>& rhs) : Are the constraints involving E and G still applicable when T and U are cv void?
-
template<class U, class G> explicit(see below) constexpr expected(expected<U, G>&& rhs) : Are the constraints involving E and G still applicable when T and U are cv void?
-
template<class... Args> constexpr explicit expected(unexpect_t, Args&&... args); : Should be "with the arguments in_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 arguments in_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> tmp from unexpected(std::move(this->error())) (which can’t throw as E is nothrow-move-constructible)
-
For !bool(*this) && bool(rhs), missing "and set has_val to true"
-
Constraint for when T is cv void should be is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.
-
Constraint for when T is 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); and expected<T, E>& operator=(unexpected<G>&& e);
-
expected<T, E>& operator=(unexpected<G>&& e);, for !bool(*this) : Missing std::move, should be "move assign unexpected(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> tmp from unexpected(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 taking std::optional<U>.
-
template<class... Args> T& emplace(Args&&... args); : By following the logic under Effects, the constraint should be is_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 be is_constructible_v<T, L, Args...> && (is_nothrow_constructible_v<T, L, Args...> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>) where L is std::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, not is_move_constructible_v.
-
In table, for bool(*this) && !bool(rhs) and is cv void, should be unexpected(std::move(rhs.error())) (missing .error())
Under Section 1.10
-
constexpr T&& expected::value() && and constexpr const T&& expected::value() const&& : Should they throw bad_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 when T is void. Does it ignore the argument and do nothing, or is it disabled entirely?
Under Section 1.12
-
operator!=: Should be "expression *x != v is well-formed.
-
operator!=: Should be "Returns: bool(x) ? *x != v : true;. If x holds an error, than is it unequal to any value v. Otherwise, !( x != v) would not be the same as x == v.
Under Section 1.14
- Constraints don't match those for member swap.
Under Section 1.17.1
-
Should be Err in constraints, instead of U.
-
template<class Err> constexpr explicit unexpected(Err&& e) : Should be unexpect_t in constraints, not unexpected.
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);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 invertedexpected<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 beWhy 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
Under Section 1.17.1
Should be
Errin constraints, instead ofU.template<class Err> constexpr explicit unexpected(Err&& e): Should beunexpect_tin constraints, notunexpected.