title: How to write c++ smartpointer for operator == / !=
body: <p>In my project, I have some mechanism in my framework, so I have designed C++ smart-pointer myself.</p>
  
  <p>But I encounter equality and inequality problem for smart-pointer.</p>
  
  <pre><code>class Ref {
  public:
      void ref(){}
      void unref(){}
  };
  
  template&lt;class T&gt;
  class SmartPtr
  {
  public:
      typedef T element_type;
  
      SmartPtr() : _ptr(nullptr) {}
      SmartPtr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr-&gt;ref(); }
      SmartPtr(const SmartPtr&amp; rp) : _ptr(rp._ptr)  { if (_ptr) _ptr-&gt;ref(); }
  
      template&lt;class Other&gt;
      SmartPtr(const SmartPtr&lt;Other&gt;&amp; rp) : _ptr(rp._ptr)
      { if (_ptr) _ptr-&gt;ref(); }
  
      ~SmartPtr() { if (_ptr) _ptr-&gt;unref();  _ptr = 0; }
  
      SmartPtr&amp; operator = (const SmartPtr&amp; rp)
      {    assign(rp);    return *this;}
  
      template&lt;class Other&gt; SmartPtr&amp; operator = (const SmartPtr&lt;Other&gt;&amp; rp)
      {   assign(rp);    return *this;}
      template&lt;class Other&gt; void assign(const SmartPtr&lt;Other&gt;&amp; rp) 
      {_ptr=rp._ptr;}
  
      operator T*() const { return _ptr; }
  
      template&lt;class U&gt;
      bool operator == (const SmartPtr&lt;U&gt;&amp; rp) const
      { return (_ptr==rp._ptr); }
  
      template&lt;class U&gt;
      friend bool operator == (const U* ptr, const SmartPtr&amp; rp)
      { return (ptr==rp._ptr); }
  
      template&lt;class U&gt;
      friend bool operator == (const SmartPtr&amp; rp, const U* ptr)
      { return (ptr==rp._ptr); }
  
  private:
      template&lt;class U&gt; friend class SmartPtr;
      T* _ptr;
  };
  </code></pre>
  
  <p>The code failed when I writing following code :</p>
  
  <pre><code>class A : public Ref {};
  class B : public A {};
  SmartPtr&lt;A&gt; a1 = new A;
  A* a2 = a1;
  bool flag = a1==a2;  // ambiguous error, error message follows
  
  SmartPtr&lt;B&gt; b = new B;
  SmartPtr&lt;A&gt; a3 = b;
  bool flag2 = a3==b;  // build pass
  </code></pre>
  
  <p>compilation error message</p>
  
  <pre><code>maybe "bool operator ==&lt;A&gt;(const U *,const ECB::SmartPtr&lt;A&gt; &amp;)"
  or    "bool operator ==&lt;A&gt;(const U *,const ECB::SmartPtr&lt;B&gt; &amp;)"
  or    "built-in C++ operator==(T1, T1)"
  or    "built-in C++ operator==(A *SmartPtr&lt;A&gt;::* , A *SmartPtr&lt;A&gt;::* )"
  </code></pre>
  
  <p>How to modify the template SmartPtr class to avoid the ambiguous errors ?</p>