Boost logo

Boost :

From: Ed Brey (brey_at_[hidden])
Date: 2000-01-03 12:14:10


The discussion regard how to check for null with smart pointers and led me to
investigate handling null on a larger scale. I think that boost should
provide a general solution to testing pointers for null above and beyond what
the IS provides. In general, I would like for the following code to work:

using boost::null;
if (some_smart_or_builtin_pointer == null)
  la_te_da();

More comprehensively, I'd like the following program to work (except where
noted):

#include <boost/utility.hpp>
#include <boost/smart_ptr.hpp>

class A {};
inline void f(char*) {}

int main()
{
  using boost::null;
  int* pi = null;
  A *pa = null;
  boost::scoped_ptr<int> ps(null);

  pi = null, pa = null, ps.reset(null);
  null != pi, null != pa, null != ps;
  pi == null, pa == null, ps == null;
  f(null);

  // The following should cause errors on a conforming compiler:
  f(!null); // error
  if (3 == null || ps == 3) // error
  delete null; // error
  return 0;
}

To accomplish this, I propose that we use the following implementation:

namespace boost {

#if !defined(BOOST_KOENIG_LOOKUP_BROKEN)
  class null_type : noncopyable {
  public:
    template<typename T> operator T*() const { return 0; }
  };
  static const null_type null;
#else
  typedef int null_type;
  static const null_type null = 0;
#endif

  template<typename T> inline bool operator==(const scoped_ptr<T>& p, const
null_type&) { return p.get() == 0; }
  template<typename T> inline bool operator==(const null_type&, const
scoped_ptr<T>& p) { return p.get() == 0; }
  template<typename T> inline bool operator!=(const scoped_ptr<T>& p, const
null_type&) { return p.get() != 0; }
  template<typename T> inline bool operator!=(const null_type&, const
scoped_ptr<T>& p) { return p.get() != 0; }

} // namespace boost

The macro is there to make this work for Visual C++ (I'm not sure if any
others). The legal code compiles fine, but so does some of the illegal code.
I tried quite a bit to find a safer null for VC, but I couldn't one that
worked for assignment and parameter passing. At least this would allow users
to write code that would become safe when they get a better compiler.

The definition of null_type and null would go into utility.hpp. The
operator== overloads would go into smart_ptr.hpp. The 4 functions could
probably be reduced to 1 by using operators.hpp, but I haven't played with
this yet. Furthermore, if all the smart pointers had a common base class, one
overload would serve for all of them. Come of think of it, a common base
class could eliminate other duplicated code: get, operator T*. Maybe it's
time to crack out the detail namespace.


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