Created on 2023-02-13.00:00:00 last changed yesterday
Proposed resolution:
This wording is relative to N4928.
Modify [optional.optional.general] as indicated:
namespace std { template<class T> class optional { public: […] template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&&); […] template<class U = remove_cv_t<T>> constexpr optional& operator=(U&&); […] template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; […] }; […] }
Modify [optional.ctor] as indicated:
template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&& v);-23- Constraints: […]
Modify [optional.assign] as indicated:
template<class U = remove_cv_t<T>> constexpr optional& operator=(U&& v);-12- Constraints: […]
Modify [optional.observe] as indicated:
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;-15- Mandates: […]
[…]template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;-17- Mandates: […]
Modify [expected.object.general] as indicated:
namespace std { template<class T, class E> class expected { public: […] template<class U = remove_cv_t<T>> constexpr explicit(see below) expected(U&& v); […] template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&); […] template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; […] }; […] }
Modify [expected.object.cons] as indicated:
template<class U = remove_cv_t<T>> constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);-23- Constraints: […]
Modify [expected.object.assign] as indicated:
template<class U = remove_cv_t<T>> constexpr expected& operator=(U&& v);-9- Constraints: […]
Modify [expected.object.obs] as indicated:
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;-16- Mandates: […]
[…]template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;-18- Mandates: […]
[ 2024-09-18; Reflector poll ]
Set status to Tentatively Ready after six votes in favour during reflector poll.
[ 2023-03-22; Reflector poll ]
Set priority to 3 after reflector poll.
While implementing P2505R5 "Monadic Functions for std::expected" we found it odd that the template type parameter for the assignment operator that accepts an argument by forwarding reference is defaulted, but the template type parameter for value_or is not. For consistency, it would seem that meow.value_or(woof) should accept the same arguments woof as does meow = woof, even when those arguments are braced-initializers.
That said, it would be peculiar to default the template type parameter of value_or to T instead of remove_cv_t<T>. For expected<const vector<int>, int> meow{unexpect, 42};, for example, meow.value_or({1, 2, 3}) would create a temporary const vector<int> for the argument and return a copy of that argument. Were the default template argument instead remove_cv_t<T>, meow.value_or({1, 2, 3}) could move construct its return value from the argument vector<int>. For the same reason, the constructor that accepts a forwarding reference with a default template argument of T should default that argument to remove_cv_t<T>. For consistency, it would be best to default the template argument of the perfect-forwarding construct, perfect-forwarding assignment operator, and value_or to remove_cv_t<T>. Since all of the arguments presented apply equally to optional, we believe optional should be changed consistently with expected. MSVCSTL has prototyped these changes successfully.History | |||
---|---|---|---|
Date | User | Action | Args |
2024-11-19 16:09:07 | admin | set | status: ready -> voting |
2024-09-18 22:19:07 | admin | set | messages: + msg14379 |
2024-09-18 22:19:07 | admin | set | status: new -> ready |
2023-03-22 22:40:39 | admin | set | messages: + msg13474 |
2023-02-19 13:27:25 | admin | set | messages: + msg13418 |
2023-02-13 00:00:00 | admin | create |