C++0x Smart Pointer Comparisons: Inconsistent, what's the rationale?

Posted by GManNickG on Stack Overflow See other posts from Stack Overflow or by GManNickG
Published on 2010-10-14T02:11:56Z Indexed on 2012/09/29 3:37 UTC
Read the original article Hit count: 108

Filed under:
|
|
|
|

In C++0x (n3126), smart pointers can be compared, both relationally and for equality. However, the way this is done seems inconsistent to me.

For example, shared_ptr defines operator< be equivalent to:

template <typename T, typename U>
bool operator<(const shared_ptr<T>& a, const shared_ptr<T>& b)
{
    return std::less<void*>()(a.get(), b.get());
}

Using std::less provides total ordering with respect to pointer values, unlike a vanilla relational pointer comparison, which is unspecified.

However, unique_ptr defines the same operator as:

template <typename T1, typename D1, typename T2, typename D2>
bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
{
    return a.get() < b.get();
}

It also defined the other relational operators in similar fashion.


Why the change in method and "completeness"? That is, why does shared_ptr use std::less while unique_ptr uses the built-in operator<? And why doesn't shared_ptr also provide the other relational operators, like unique_ptr?

I can understand the rationale behind either choice:

  • with respect to method: it represents a pointer so just use the built-in pointer operators, versus it needs to be usable within an associative container so provide total ordering (like a vanilla pointer would get with the default std::less predicate template argument)
  • with respect to completeness: it represents a pointer so provide all the same comparisons as a pointer, versus it is a class type and only needs to be less-than comparable to be used in an associative container, so only provide that requirement

But I don't see why the choice changes depending on the smart pointer type. What am I missing?


Bonus/related: std::shared_ptr seems to have followed from boost::shared_ptr, and the latter omits the other relational operators "by design" (and so std::shared_ptr does too). Why is this?

© Stack Overflow or respective owner

Related posts about c++

Related posts about c++11