Why does std::unique_ptr have an equality operator?

Viewed 582

I've been thinking about it recently, and the only argument I can see for having an equality operator for std::unique_ptr is for completeness so all of the smart pointers in the standard template library have it. But unless you've done something wrong, I can't see any example where it might return true.

It's obviously possible to do something like:

int* a = new int(1);
std::unique_ptr<int> u_a1(a);
std::unique_ptr<int> u_a2(a);

if(u_a1 == u_a2)
{
    std::cout << "I'm double deleting soon" << std::endl;
}

But doesn't the inclusion of the operator just allow for people to make these kind of mistakes without the compiler throwing an error? Wouldn't it make more sense to remove it, or am I missing something?

3 Answers

Equality actually can return true. The simplest case is two empty pointers:

std::unique_ptr u_a1;
std::unique_ptr u_a2;

if (u_a1 == u_a2) // ...

The operators also allow comparing unique_ptr<T, D> objects with different types, so you might have two different deleter types which will do different things to the same pointer on cleanup. Or even some deleter other than the default deleter which intentionally can do the same thing more than once (a counter?).

The presence of the operators might also make the type valid in some templates which would happen to want to compare objects of its dependent types.

Smart pointers are meant to have the same semantics as raw pointers, just with automated ownership semantics added. Since raw pointers can be compared, so too can their smart pointer counterparts. Whether or not it makes sense to compare 2 unique_ptrs is a separate matter.

You can use this to check if a unique_ptr is null, and you can also have references to unique_ptr's so you can use this to see if they refer to the same unique_ptr.

Related