Archived

This forum has been archived. Please start a new discussion on GitHub.

[3.4.2] IceUtil/Handle.h comparing objects not pointers

//
// g++ -o test -l IceUtil test.cc
//

#include <cassert>
#include <iostream>

#include <IceUtil/Handle.h>
#include <IceUtil/Shared.h>

class Demo : public ::IceUtil::SimpleShared
{
  public:
    Demo (int x = 0) :
      x_(x)
    {
    }
    bool operator== (const Demo& d)
    {
      ::std::cout << "erroneous object comparison invoked" << ::std::endl;
      return x_ == d.x_;
    }
  protected:
    virtual ~Demo ()
    {
    }
  private:
    int x_;
};
typedef ::IceUtil::Handle<Demo> DemoPtr;

int main ()
{
  DemoPtr a (new Demo (1));
  DemoPtr b (new Demo (1));

  assert (a == b);  // this succeeds, but should fail according to the documented semantics

  // Handle.h
  //
  // template<typename T, typename U>
  // inline bool operator==(const HandleBase<T>& lhs, const HandleBase<U>& rhs)
  // {
  //    T* l = lhs.get();
  //    U* r = rhs.get();
  //    if(l && r)
  //    {
  //      return *l == *r;
  //    }
  //    return !l && !r;
  // }
  //
  // Sometimes less is more.  How about simply: return lhs.get() == rhs.get();
  // 
  return 0;
}


Comments

  • benoit
    benoit Rennes, France
    Hi Phil,

    Thanks for the bug report. The documentation is wrong actually. It is the intended behavior for the IceUtil::Handle comparison operators to rely on the class comparison operators. It's the responsibility of the class to decide how the handle comparison behaves (for example, if your class inherits from Ice::LocalObject it will use address comparison by default).

    Cheers,
    Benoit.
  • Benoit,

    OK. You might place special emphasis in the documentation on this point as it deviates from other implementations of smart pointers (c++0x, tr1, boost, boost tr1) -- all of them have pointer comparison semantics for operator==, operator!=, etc. Anyone using IceUtil::Handle as a substitute smart pointer can get thrown by this unusual twist.

    Phil