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:
std::less
predicate template argument)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?
This was a defect in drafts of C++11; a defect report was opened to change the std::unique_ptr
relational operator overloads to use std::less
: see LWG Defect 1297.
This was fixed in time for the final C++11 specification. C++11 §20.7.1.4[unique.ptr.special]/5 specifies that the operator<
overload:
Returns:
less<CT>()(x.get(), y.get())
where x
and y
are the two operands of the operator and CT
is the common type of the two pointers (since pointers to different types, e.g. with different cv-qualifications, can be compared).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With