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?