Boost logo

Boost :

Subject: [boost] [intrusive_ptr] Why are comparison operators not friends?
From: Carsten Fuchs (carsten.fuchs_at_[hidden])
Date: 2012-08-05 04:40:08


Hi all,

I was just (re-)reading item 46, "Define non-member functions inside templates when type
conversions are desired", in Scott Meyers "Effective C++, 3rd edition", and was
wondering how and why the comparison operators for intrusive_ptr work when used with
NULL, even though they're not friend functions as described in Scott Meyer's item 46.

That is, the example program below compiles and links fine both with GCC 4.6 as well as
with Visual C++ 2010 -- but how does do the compilers match the == operator, whose right
operand is NULL, an int value?

If I try to use the exact same templated binary operators like this in my own classes,
and want NULL matched to one of the T* or U* operands, then I have to do it with friend
functions or else the compilers don't find a match.

Why does it work here?

Best regards,
Carsten

#include <boost/intrusive_ptr.hpp>
#include <iostream>

class CRefCounted
{
     public:

     CRefCounted() : RefCount(0) {}

     long RefCount;
};

void intrusive_ptr_add_ref(CRefCounted* p) { ++(p->RefCount); }
void intrusive_ptr_release(CRefCounted* p) { if (--(p->RefCount) == 0) delete p; }

int main()
{
     using namespace boost;

     intrusive_ptr<CRefCounted> p(new CRefCounted());

     // I'd expect the next line of code to fail compilation, because the compiler
     // cannot find a match for operator == with left operand of type
     // intrusive_ptr<CRefCounted> and right operand of type int, but they do!
     if (p == NULL)
         std::cout << "p == NULL\n";
     else
         std::cout << "p != NULL\n";
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk