4

As you can see in the following code, I attempt to have some default arguments of the function "initialize" that are union. How to change the definition of the function "initialize" to make it compatible with C++ before C++ 11? Do I need to add some constructors to RedBlackPointer? If so, how?

template <typename T> class RedBlackNode{
protected:
    union RedBlackPointer{
        RedBlackNode *node;
        struct{
            unsigned value:1;   // for color / other info
        }flag;
    }left, right, parent;

    T key;

public:
    void initialize(T key, RedBlackPointer left = {(RedBlackNode*)0},
            RedBlackPointer right = {(RedBlackNode*)0},
            RedBlackPointer parent = {(RedBlackNode*)0}){
        this->key = key;
        this->left = left; this->right = right;
        this->parent = parent;
    }
}
timrau
  • 22,578
  • 4
  • 51
  • 64
Firas
  • 467
  • 4
  • 15
  • 2
    Don't you have a bug in this code? I think that you want to store `node` pointer and `value` at the same time, so you shouldn't use union for that purpose. – ciechowoj Mar 21 '15 at 07:49
  • Maybe [this](http://stackoverflow.com/questions/8417759/union-and-struct-initialization) will help. – ciechowoj Mar 21 '15 at 07:50
  • ISO C++03 8.5.1[dcl.init.aggr]/15: When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer for the first member of the union. – myaut Mar 21 '15 at 08:43

1 Answers1

1

Indeed, the extended initialization lists are not available before C++11.

As long as you keep in mind that only ONE member in a union can be active at any time, you can easily solve the issue with a default constructor:

template <typename T> class RedBlackNode{
protected:
    union RedBlackPointer{
        RedBlackPointer() : node(0) { }  // <==== default constructor
        RedBlackNode *node;
        struct{
            unsigned value:1;   // for color / other info
        }flag;
    }left, right, parent;
    T key;
public:
    void initialize(T key, RedBlackPointer left = RedBlackPointer(), //refer to default ctor
            RedBlackPointer right = RedBlackPointer(),
            RedBlackPointer parent = RedBlackPointer()){
        this->key = key;
        this->left = left; this->right = right;
        this->parent = parent;
    }
    void show() {
        cout<<left.node<<","<<right.node<<","<<parent.node<<","<<key<<endl;
    }
};   //  <=== ; 

And here how to demonstrate that it works:

 RedBlackNode<int> N; 
 N.initialize(5); 
 N.show();

Here a live demo and here with a compiler that rejected your initial code.

Additional comment:

One thing puzzles me: in your union you combine a pointer with a one bit flag.

This is not shoking per se: it could imagine it being a trick to avoid overhead of pointer allocation, when sometimes the value poitned to is small enough to be stored directly in the tree.

However in this case, it's not clear how you will know wich is the active member (i.e. when to use the pointer, and when to use the flag is used).

So I'd suggest you cross check that there is not a mistake / forgottoen element here.

Christophe
  • 68,716
  • 7
  • 72
  • 138