shared_ptr
converting constructorsSection: 20.3.2.2.2 [util.smartptr.shared.const] Status: C++20 Submitter: Casey Carter Opened: 2019-07-10 Last modified: 2021-02-25
Priority: 0
View other active issues in [util.smartptr.shared.const].
View all other issues in [util.smartptr.shared.const].
View all issues with C++20 status.
Discussion:
Issue 2875 added 20.3.2.2.2 [util.smartptr.shared.const] paragraph 13:
Remarks: Whenwhich pertains to the four constructor overloads:T
is an array type, this constructor shall not participate in overload resolution unlessis_move_constructible_v<D>
istrue
, the expressiond(p)
is well-formed, and eitherT
isU[N]
andY(*)[N]
is convertible toT*
, orT
isU[]
andY(*)[]
is convertible toT*
. WhenT
is not an array type, this constructor shall not participate in overload resolution unlessis_move_constructible_v<D>
istrue
, the expressiond(p)
is well-formed, andY*
is convertible toT*
.
which is fine (ignoring for now that two occurrences of "this constructor" should read "these constructors") for the two overloads with a template parametertemplate<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);
Y
, but not so much for the
two with no such template parameter.
MSVC ignores the constraints on Y
for the overloads with no such template parameter,
whereas libstdc++ and libc++ seem to ignore all of the constraints for those overloads (See
Compiler Explorer). We should fix the broken wording,
ideally by requiring the MSVC interpretation - the nullptr_t
constructors participate in
overload resolution only when is_movable_v<D>
is true
and d(p)
is
well-formed - so concepts and traits that check constructibility are correct.
[2019-11-17 Issue Prioritization]
Status to Tentatively Ready and priority to 0 after six positive votes on the reflector.
Proposed resolution:
This wording is relative to N4835.
Modify 20.3.2.2.2 [util.smartptr.shared.const] as indicated:
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);-?- Constraints:
is_move_constructible_v<D>
istrue
, andd(p)
is a well-formed expression. For the first two overloads:
If
T
is an array type, then eitherT
isU[N]
andY(*)[N]
is convertible toT*
, orT
isU[]
andY(*)[]
is convertible toT*
.If
T
is not an array type, thenY*
is convertible toT*
.-9-
RequiresExpects: Construction ofd
and a deleter of type […][…]
-13- Remarks: WhenT
is an array type, this constructor shall not participate in overload resolution unlessis_move_constructible_v<D>
istrue
, the expressiond(p)
is well-formed, and eitherT
isU[N]
andY(*)[N]
is convertible toT*
, orT
isU[]
andY(*)[]
is convertible toT*
. WhenT
is not an array type, this constructor shall not participate in overload resolution unlessis_move_constructible_v<D>
istrue
, the expressiond(p)
is well-formed, andY*
is convertible toT*
.