Title
convertible-to-non-slicing seems to reject valid case
Status
c++23
Section
[range.subrange]
Submitter
S. B. Tam

Created on 2020-07-26.00:00:00 last changed 12 months ago

Messages

Date: 2021-10-14.09:56:08

Proposed resolution:

This wording is relative to N4885.

  1. Modify [range.subrange] as indicated:

    namespace std::ranges {
      template<class From, class To>
        concept uses-nonqualification-pointer-conversion = // exposition only
          is_pointer_v<From> && is_pointer_v<To> &&
          !convertible_to<remove_pointer_t<From>(*)[], remove_pointer_t<To>(*)[]>;
    
      template<class From, class To>
        concept convertible-to-non-slicing = // exposition only
          convertible_to<From, To> &&
          !uses-nonqualification-pointer-conversion<decay_t<From>, decay_t<To>>;
          !(is_pointer_v<decay_t<From>> &&
          is_pointer_v<decay_t<To>> &&
          not-same-as<remove_pointer_t<decay_t<From>>, remove_pointer_t<decay_t<To>>>
          );
      […]
    }
    […]
    
Date: 2021-10-14.00:00:00

[ 2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP. ]

Date: 2021-06-15.00:00:00

[ 2021-06-23; Reflector poll ]

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

Date: 2021-05-19.00:00:00

[ 2021-05-19 Tim adds wording ]

The wording below, which has been implemented and tested on top of libstdc++, uses the same technique we use for unique_ptr, shared_ptr, and span. It seems especially appropriate to have feature parity between subrange and span in this respect.

Date: 2020-08-15.00:00:00

[ 2020-08-21; Reflector prioritization ]

Set priority to 3 after reflector discussions.

Date: 2020-07-26.00:00:00

Consider

#include <ranges>

int main()
{
  int a[3] = { 1, 2, 3 };
  int* b[3] = { &a[2], &a[0], &a[1] };
  auto c = std::ranges::subrange<const int*const*>(b);
}

The construction of c is ill-formed because convertible-to-non-slicing<int**, const int*const*> is false, although the conversion does not involve object slicing.

I think subrange should allow such qualification conversion, just like unique_ptr<T[]> already does.

(Given that this constraint is useful in more than one context, maybe it deserves a named type trait?)

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2021-10-14 09:56:08adminsetmessages: + msg12119
2021-10-14 09:56:08adminsetstatus: voting -> wp
2021-09-29 12:57:28adminsetstatus: ready -> voting
2021-06-23 14:16:45adminsetmessages: + msg11956
2021-06-23 14:16:45adminsetstatus: new -> ready
2021-05-20 01:13:33adminsetmessages: + msg11823
2021-05-20 01:13:33adminsetmessages: + msg11822
2020-08-21 13:43:37adminsetmessages: + msg11440
2020-07-26 00:00:00admincreate