null assignment in a template



Please excuse me if there is a better place for this post. I could not find one in MS's communities. My question is about template programming in C++, not really about STL.

// Initialised supplies an initial value in the variable declaration itself
// NOTE: for non-scalar types (such as floating point types) this template won't compile
// due to the fact that it is illegal to declare a template with a non-scalar value
// Use Uninitialised instead, and declare the value in its explicit ctor
template <typename T, T * zero>
struct Initialised<T*, zero>
{
Initialised() : m_value(zero) { }
template <typename U> Initialised(const U* that) : m_value(that) { }
template <typename U> T* & operator = (const U* that) { if (m_value != that) m_value = that; return *this; }

T* & operator = (const int constant) { return m_value = constant; }

operator T* & () { return m_value; }
operator const T* & () const { return m_value; }
T * m_value; // the plain old data
};

What I really want is to allow myself to declare a plain old pointer and guarantee that its initialized in the constructor or point of declaration, to make it much easier to avoid uninitialized variables issues.

The above appears to do exactly that.

The only fly in the ointment is that the following fails:

Initialised<Widget*, new Widget(1,2,3)> m_pWidget;
....blah - blah
....some code...
....later
m_pWidget = NULL;

Since this line evaluates to Initialised::operator = (int) { m_value = int; }

There is no conversion from int to Widget*!

Now, I can certainly do the obnoxious thing and cast int to Widget* in operator=(int), and then leave it up to the user to ensure that any int assignments are always the value NULL, but that's just sloppy and asking for trouble.

I can go back to my code that uses m_pWidget and force all null-assignments to be type-cast at the point of assignment:

m_pWidget = (Widget*)NULL;

Not the worst idea in the universe, but I have a lot of places where I'd like to replace the current variable / member declarations with Initialised<Type,zero> declarations, and I don't want to have to comb through many hundreds of lines of code to correct every NULL assignment.

What I Really Want(tm) is to be able to have m_pWidget = NULL evaluate to a valid expression, and m_pWidget = <any-other-integer-or-other-non-convertible-type> to error with "no conversion from <type> to Widget*".

I keep thinking that if I can make the operator = (x) partially specialized for operator = (NULL) I would be golden! However, everything I've tried leads to a compiler error. I need a type for NULL which is different from not-null and for the compiler to identify that such that the function called in m_pWidget = NULL is one function (that is legal), and m_pWidget = 5 results in an illegal assignment.

Any ideas / feedback would be *hugely* appreciated.

Steve Wolf

PS: Its Initialised instead of Initialized due to the fact that I already have an Initialized template for POD structs, and I wanted one for simple singular data types as well.

Relevant Pages

  • Simple script annimation problem usig swing
    ... To change this template, ... public void destroy{ ... public state cstate; ... public static int respawn = 20; ...
    (comp.lang.java.programmer)
  • Re: Simple script annimation problem usig swing
    ... To change this template, ... public void destroy{ ... public state cstate; ... public static int respawn = 20; ...
    (comp.lang.java.programmer)
  • implementation details
    ... template class ) ... Retrieve then I'd like to implement some sort of overrun check. ... BUFFER(); ... unsigned int retrieve_count; ...
    (comp.lang.cpp)
  • Re: Replacing merge fields in headers/footers
    ... database, and a newly populated document can be requested at any time. ... to my way of thinking is to have a merge template ... I'm using exactly the same code to populate the fields in the ... >> private FileStream PopulateTemplateDocument(int theFileID, ...
    (microsoft.public.word.vba.general)
  • friend ostream& operator<< (ostream&, Array<T>&);
    ... Array(int itsSize = DefaultSize); ... int GetSize() const ... make sure the function template has already been declared and add after ... // implement the Constructor ...
    (alt.comp.lang.learn.c-cpp)