我正在尝试在类中使用模板化struct
,但无法弄清楚如何正确声明它
template<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;
};
我一直在犯错误#34;节点不是一种类型&#34;和&#34;模板名称Node的使用无效,没有参数列表&#34;。
我知道如何模拟单个class
以及类内外的方法,但这是我第一次使用struct
并尝试在类中使用模板struct
。
在类中声明和使用templated struct
的正确方法是什么。
答案 0 :(得分:5)
如果Node在内部使用var
类型,那么它也应该由它模板化:
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;
};
修改强>:
这是我第一次使用struct并尝试在类中使用模板化结构。什么是在类中声明和使用模板化结构的正确方法。
如果您的树数据总是具有相同的类型,则可以不使用模板化Tree类:
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;
};
第二次修改
节点的变体实现:
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;
};
这里的想法是以相同的方式识别要应用于所有节点值的所有操作(在我的示例代码中,这意味着“将值转换为字符串”)和(首先)将它们声明为{中的抽象操作{1}},然后根据值类型实现它们(作为Node
中的虚函数实现)。
这将允许您在ValueNode
类中对节点中有多种类型的事实进行抽象。
也就是说,如果您使用boost,则应该在原始代码中使用Tree
或boost::variant
代替Node中的typename var。
答案 1 :(得分:2)
“
Node
不是类型”和“使用没有参数列表的模板名称Node
无效”
编译器说你到底出了什么问题。 Node
确实不是一种类型。 Node
是一个模板。
类型包括Node<int>
,Node<std::string>
,Node<T>
(Tree
}内部和Node<var>
(Node
内部)。
答案 2 :(得分:-1)
只需将Node
声明更改为Node<TypeName>
,编译器就会抱怨Node
不是一个类型,但它不是,但Node<var>
是一个类这种情况。