如何在 C++ 类中使用模板化结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26907770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:41:55  来源:igfitidea点击:

How to use templated struct in class c++

c++templatesstruct

提问by Aistis Taraskevicius

I am trying to use templated structwithin a class, but cant figure out how to declare it properly

我正在尝试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;
};

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 classand methods within or outside the class, but this is first time I am using structand trying to use templated structwithin a class. What is proper way to declare and use templated structwithin a class.

我知道如何class在类内或类外对单个和方法进行模板化,但这是我第一次使用struct并尝试struct在类内使用模板化。templated struct在类中声明和使用的正确方法是什么。

回答by utnapistim

If Node uses vartype internally, then it should be templated by it as well:

如果 Node 在var内部使用type,那么它也应该被它模板化:

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.

这是我第一次使用 struct 并尝试在类中使用模板化结构。在类中声明和使用模板化结构的正确方法是什么。

You can get away with not templating Tree class, if your tree data always has the same type:

如果您的树数据始终具有相同的类型,您可以不模板化 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;
};

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).

这里的想法是以相同的方式识别要应用于所有节点值的所有操作(在我的示例代码中,这意味着“将值转换为字符串”)并且(首先)将它们声明为 中的抽象操作Node,然后实现它们取决于值类型(如 中的虚函数实现ValueNode)。

This will allow you to make abstraction of the fact you have multiple types in the nodes, in the Treeclass.

这将允许您抽象您在类中的节点中有多种类型的事实Tree

That said, if you use boost, you should probably use boost::variantor boost::anyin place of typename var in Node, in your original code.

也就是说,如果您使用 boost,您可能应该在原始代码中使用boost::variantboost::any代替 Node 中的 typename var。

回答by GingerPlusPlus

"Nodeis not a type" and "Invalid use of template-name Nodewithout an argument list"

Node不是类型”和“模板名称的无效使用Node没有参数列表

Compiler says you exactly what is wrong. Nodeis indeed not a type. Nodeis a template.

编译器告诉你到底哪里错了。Node确实不是一种类型。Node是一个模板。

The types are for example Node<int>, Node<std::string>, Node<T>(inside Tree) and Node<var>(inside Node).

例如Node<int>,类型是, Node<std::string>, Node<T>(inside Tree) 和Node<var>(inside Node)。

回答by Keegan Fisher

Just change the Nodedeclarations to Node<TypeName>, the compiler is complaining that Nodeis not a type, and it isn't, but Node<var>is a class in this case.

只需将Node声明更改为Node<TypeName>,编译器就会抱怨它Node不是类型,它不是,但Node<var>在这种情况下是一个类。