How to use templated struct in class c++
Solution 1
If Node uses var
type internally, then it should be templated by it as well:
template<typename var>
struct Node
{
var value;
Node* left;
Node* right;
};
template<typename T>
class Tree
{
public:
Tree();
~Tree();
void insert(T key, Node<T> *node);
Node<T>* search(T key, Node<T> *node);
void deleteTree(Node<T> *node);
void inOrderTraversePrint(Node<T>* node);
void preOrderTraversePrint(Node<T>* node);
void postOrderTraversePrint(Node<T>* node);
Node<T>* getRoot();
void resetRoot();
private:
Node<T>* root;
};
Edit:
this is first time I am using struct and trying to use templated struct within a class. What is proper way to declare and use templated struct within a class.
You can get away with not templating Tree class, if your tree data always has the same type:
class Tree
{
public:
Tree();
~Tree();
void insert(var key, Node<int> *node);
Node* search(var key, Node<int> *node);
void deleteTree(Node<int> *node);
void inOrderTraversePrint(Node<int>* node);
void preOrderTraversePrint(Node<int>* node);
void postOrderTraversePrint(Node<int>* node);
Node<int>* getRoot();
void resetRoot();
private:
Node<int>* root;
};
Second Edit
Variant implementation for nodes:
class Node
{
virtual std::string ToString() = 0; // convert value to string
virtual ~Node() = default;
Node *left, *right;
};
template<typename T>
class ValueNode: public Node
{
T value_;
public:
ValueNode(T value): Node{ nullptr, nullptr }, value_{ std::move(value) } {}
std::string ToString() override;
{
std::ostringstream oss;
oss << value_;
return oss.str();
}
virtual ~ValueNode() = default;
};
class Tree
{
public:
Tree();
~Tree();
template<typename var>
void insert(var key, Node *node)
{
// insert new ValueNode<var>{ key } here
}
template<typename var>
Node* search(var key, Node *node);
void deleteTree(Node *node);
void inOrderTraversePrint(Node* node);
void preOrderTraversePrint(Node* node);
void postOrderTraversePrint(Node* node);
Node* getRoot();
void resetRoot();
private:
Node* root;
};
The idea here is to identify all operations to apply to all node values in the same way (in my example code, that means "conversion of the value to a string") and (first) declare them as abstract operations in Node
, then implement them depending on the value type (as virtual function implmentations in ValueNode
).
This will allow you to make abstraction of the fact you have multiple types in the nodes, in the Tree
class.
That said, if you use boost, you should probably use boost::variant
or boost::any
in place of typename var in Node, in your original code.
Solution 2
"
Node
is not a type" and "Invalid use of template-nameNode
without an argument list"
Compiler says you exactly what is wrong. Node
is indeed not a type. Node
is a template.
The types are for example Node<int>
, Node<std::string>
, Node<T>
(inside Tree
) and Node<var>
(inside Node
).
Aistis Taraskevicius
Updated on April 02, 2020Comments
-
Aistis Taraskevicius about 4 years
I am trying to use templated
struct
within a class, but cant figure out how to declare it properlytemplate<typename var> struct Node { var value; Node* left; Node* right; }; class Tree { public: Tree(); ~Tree(); template<typename var> void insert(var key, Node *node); template<typename var> Node* search(var key, Node *node); void deleteTree(Node *node); void inOrderTraversePrint(Node* node); void preOrderTraversePrint(Node* node); void postOrderTraversePrint(Node* node); Node* getRoot(); void resetRoot(); private: Node* root; };
I keep getting couple errors " Node is not a type" and "Invalid use of template-name Node without an argument list".
I know how to template single
class
and methods within or outside the class, but this is first time I am usingstruct
and trying to use templatedstruct
within a class. What is proper way to declare and usetemplated struct
within a class. -
Aistis Taraskevicius over 9 yearsWell tree doesnt store any data, node stores int, but I want it to be able to store other data types such as string
-
utnapistim over 9 years@AistisTaraskevicius, I will edit my answer to show that as well.
-
Aistis Taraskevicius over 9 yearsCheers, I actually got it work after your first post with templated class, but could you explain in more detail what your second edit does, does it allows storing all types as a string?
-
utnapistim over 9 years@AistisTaraskevicius, it allows interpretation of all values as strings. Consider this code:
Node* n = new ValueNode<int>{ 20 };
When you calln->ToString();
you get a string representation of the node, without caring that the node contains anint
(if it contained some other type, you would still get a string). This will allow you to treat allNode
specializations the same, regarding on what type they are specialized on (and make client code easier and uniform). -
Aistis Taraskevicius over 9 yearsCheers, sounds definitely useful.
-
Alexander Patrikalakis about 7 yearsYou should provide a code snippet of the solution to illustrate.