unique_ptr
's relational operator functions should induce a total orderSection: 20.3.1.6 [unique.ptr.special] Status: Resolved Submitter: Daniel Krügler Opened: 2009-12-23 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [unique.ptr.special].
View all issues with Resolved status.
Discussion:
The comparison functions of unique_ptr
currently directly delegate to
the underlying comparison functions of unique_ptr<T, D>::pointer
.
This is disadvantageous, because this would not guarantee to induce a total
ordering for native pointers and it is hard to define a total order for mixed
types anyway.
The currently suggested resolution for shared_ptr
comparison as of
1262 uses a normalization strategy: They perform the comparison on
the composite pointer type (7.6.9 [expr.rel]). This is not
exactly possible for unique_ptr
in the presence of user-defined
pointer-like types but the existing definition of std::duration
comparison as of 30.5.7 [time.duration.comparisons] via
common_type
of both argument types demonstrates a solution of this
problem. The approach can be seen as the general way to define a composite
pointer type and this is the approach which is used for here suggested
wording change.
For consistency reasons I would have preferred the same normalization strategy
for ==
and !=
, but Howard convinced me not to do so (now).
[ 2010-11-03 Daniel comments and adjustes the currently proposed wording changes: ]
Issue 1401 is remotely related. Bullet A of its proposed resolution
provides an alternative solution for issue discussed here and addresses NB comment GB-99.
Additionally I updated the below suggested wording in regard to the following:
It is an unncessary requirement that the below defined effective composite pointer-like
type CT
satisfies the LessThanComparable
requirements. All what is
needed is, that the function object type less<CT>
induces a strict
weak ordering on the pointer values.
[2011-03-24 Madrid meeting]
Resolved by 1401
Proposed resolution:
Change 20.3.1.6 [unique.ptr.special]/4-7 as indicated: [The implicit
requirements and remarks imposed on the last three operators are the same as for
the first one due to the normative "equivalent to" usage within a Requires
element, see 16.3.2.4 [structure.specifications]/4. The effects of this
change are that all real pointers wrapped in a unique_ptr
will order
like shared_ptr
does.]
template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);? Requires: Let
CT
becommon_type<unique_ptr<T1, D1>::pointer, unique_ptr<T2, D2>::pointer>::type
. Then the specializationless<CT>
shall be a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.4 Returns:
less<CT>()(x.get(), y.get())
.x.get() < y.get()? Remarks: If
unique_ptr<T1, D1>::pointer
is not implicitly convertible toCT
orunique_ptr<T2, D2>::pointer
is not implicitly convertible toCT
, the program is ill-formed.template <class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);5 Effects: Equivalent to
return !(y < x)
Returns:.x.get() <= y.get()
template <class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);6 Effects: Equivalent to
return (y < x)
Returns:.x.get() > y.get()
template <class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);7 Effects: Equivalent to
return !(x < y)
Returns:.x.get() >= y.get()