Reputation: 1129
I am puzzled as to why this is needed or if I have got something else wrong which is causing my problem.
I have some template based code...
template <typename T>
class redblacknode{
private:
T value;
public:
int colour;
redblacknode* up;
redblacknode* left;
redblacknode* right;
redblacknode(T& v);
redblacknode(redblacknode* node);
redblacknode(redblacknode& node);
redblacknode* grandparent() const;
redblacknode* uncle() const;
redblacknode* sibling() const;
T& getvalue();
bool bothchildrenblack() const;
bool equals(redblacknode*) const;
bool lessthan(redblacknode*) const;
void assign(redblacknode*);
void showinorder(redblacknode*) const;
void showpreorder(redblacknode*) const;
void showpostorder(redblacknode*) const;
};
The puzzling thing is that if I declare a class I want to use in this like this...
class pagechain{
....
pagechain(long page);
....
};
pagechain::pagechain(long page)
{
pagenumber = page;
}
....
pagechain dummy = pagechain(initialvalue);
redblacknode<pagechain>(dummy);
This code fails - saying I need to explicitly initialise T
./redblack.hpp:31:3: error: constructor for 'redblacknode<pagechain>' must explicitly initialize the member 'value' which does not have a default constructor
redblacknode(T& v);
But I add a dumb constructor to pagechain...
pagechain(){};
The code compiles... what causes this behaviour/what have I got wrong?
Upvotes: 0
Views: 723
Reputation: 20044
The compiler tells you to explicitly initialize value
(not T), read the error message exactly.
If you declare a member variable
T value;
the compiler wants to generate initialization code for the variable "value" as part of any constructor of redblacknode
. This works automatically when T
has a ctor without parameters. If there is no such ctor (and when do don't provide one, there is none for pagechain
, since you have added a ctor with a parameter, which disables the auto generated parameterless ctor), you can instead provide an explicit initialization like
public redblacknode::redblacknode(T& v)
:value(0)
{
}
(you have to implement all redblacknode
constructors that way).
Upvotes: 2
Reputation: 7766
Though I can't see the code for your constructor redblacknode(T& v)
, I'm guessing it looks something like the following:
template <typename T> redblacknode<T>::redblacknode(T& v) {
value = v;
}
What this is doing is calling T
's default constructor, then assigning it the value of v
. What you want to do instead is to use an initializer statement:
template <typename T> redblacknode<T>::redblacknode(T& v)
: value(v)
{
}
This way you don't need to default-construct value
, as value
is now constructed in one step, instead of two.
Upvotes: 2