This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 1297. `unique_ptr`'s relational operator functions should induce a total order

Section: 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 29.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` be `common_type<unique_ptr<T1, D1>::pointer, unique_ptr<T2, D2>::pointer>::type`. Then the specialization `less<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 to `CT` or `unique_ptr<T2, D2>::pointer` is not implicitly convertible to `CT`, 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()`.