|
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