Created on 2023-12-25.00:00:00 last changed 9 months ago
Proposed resolution:
This wording is relative to N4971.
Modify [util.smartptr.shared.const] as indicated:
template<class Y> explicit shared_ptr(Y* p);-3- Constraints: When T is an array type, the expression delete[] p is well-formed and either:
T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
- —
is_bounded_array_v<T> && is_convertible_v<Y(*)[rank_v<T>], T*>
istrue
, or- —
is_unbounded_array_v<T> && is_convertible_v<Y(*)[], T*>
istrue
.When T is not an array type, the expression delete p is well-formed and
Y* is convertible to T*is_convertible_v<Y*, T*>
istrue
.[…]
template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template<class D> shared_ptr(nullptr_t p, D d); template<class D, class A> shared_ptr(nullptr_t p, D d, A a);-9- Constraints: is_move_constructible_v<D> is true, and d(p) is a well-formed expression. For the first two overloads:
(9.1) — If T is an array type, then either:
T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
- —
is_bounded_array_v<T> && is_convertible_v<Y(*)[rank_v<T>], T*>
istrue
, or- —
is_unbounded_array_v<T> && is_convertible_v<Y(*)[], T*>
istrue
.(9.2) — If T is not an array type, then
Y* is convertible to T*is_convertible_v<Y*, T*>
istrue
.[…]
[ 2024-03-15; Jonathan provides alternative wording ]
Can we just use is_convertible_v<Y(*)[N], T*>
?
With `enable_if`-style SFINAE an invalid type will cause substitution failure
and with a requires-clause the constraints won't be satisfied.
Either way we get the desired outcome.
Also, the delete expression is already required to be well-formed, which
rules out function types, so that part of the issue is NAD.
[ 2024-03-15; Reflector poll ]
Set priority to 4 after reflector poll.
Jens pointed out that "convertible", as a core language concept, goes from "expression" to "type", not from "type" to "type".
This wording is relative to N4971.
Modify [util.smartptr.shared.const] as indicated:
template<class Y> explicit shared_ptr(Y* p);-3- Constraints: When T is an array type, the expression delete[] p is well-formed and either T is U[N] and Y(*)[N] is a valid type and convertible to T*, or T is U[] and Y(*)[] is a valid type and convertible to T*. When T is not an array type, the expression delete p is well-formed and Y* is convertible to T*.
[…]template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template<class D> shared_ptr(nullptr_t p, D d); template<class D, class A> shared_ptr(nullptr_t p, D d, A a);-9- Constraints: is_move_constructible_v<D> is true, and d(p) is a well-formed expression. For the first two overloads:
(9.1) — If T is an array type, then either T is U[N] and Y(*)[N] is a valid type and convertible to T*, or T is U[] and Y(*)[] is a valid type and convertible to T*.
(9.2) — If T is not an array type, then Y* is convertible to T*.
[…]
Currently, [util.smartptr.shared.const]/3 and /9.1 says Y(*)[N] and Y(*)[], however, they may be invalid types when Y is an array type of unknown bound or a function type. Presumably, the constraints should be satisfied only when the mentioned Y(*)[N] or Y(*)[] is valid.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-03-15 11:28:44 | admin | set | messages: + msg14010 |
2024-03-15 11:28:44 | admin | set | messages: + msg14009 |
2024-01-13 14:20:50 | admin | set | messages: + msg13908 |
2023-12-25 00:00:00 | admin | create |