Title
Monad mo' problems
Status
wp
Section
[optional.optional.general][expected.object.general]
Submitter
Casey Carter

Created on 2023-02-13.00:00:00 last changed 3 weeks ago

Messages

Date: 2024-11-28.21:40:31

Proposed resolution:

This wording is relative to N4928.

  1. 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&&) &&;
        […]
      };
      […]
    }
    
  2. Modify [optional.ctor] as indicated:

    template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&& v);
    

    -23- Constraints: […]

  3. Modify [optional.assign] as indicated:

    template<class U = remove_cv_t<T>> constexpr optional& operator=(U&& v);
    

    -12- Constraints: […]

  4. 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: […]

  5. 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&&) &&;
        […]
      };
      […]
    }
    
  6. 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: […]

  7. Modify [expected.object.assign] as indicated:

    template<class U = remove_cv_t<T>>
      constexpr expected& operator=(U&& v);
    

    -9- Constraints: […]

  8. 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: […]

Date: 2024-11-28.21:40:31

[ Wrocław 2024-11-23; Status changed: Voting → WP. ]

Date: 2024-09-15.00:00:00

[ 2024-09-18; Reflector poll ]

Set status to Tentatively Ready after six votes in favour during reflector poll.

Date: 2023-03-15.00:00:00

[ 2023-03-22; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2023-02-13.00:00:00

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-28 21:40:31adminsetmessages: + msg14469
2024-11-28 21:40:31adminsetstatus: voting -> wp
2024-11-19 16:09:07adminsetstatus: ready -> voting
2024-09-18 22:19:07adminsetmessages: + msg14379
2024-09-18 22:19:07adminsetstatus: new -> ready
2023-03-22 22:40:39adminsetmessages: + msg13474
2023-02-19 13:27:25adminsetmessages: + msg13418
2023-02-13 00:00:00admincreate