【问题标题】:Tree with Nodes can be 3 different types (string, int or float)带节点的树可以是 3 种不同的类型(字符串、整数或浮点数)
【发布时间】:2020-07-30 08:35:44
【问题描述】:

需要实现任意树,其中每个节点可以是字符串、整数或实数,并且有任意数量的子节点,也是这三种类型之一(子节点可以是不同的类型)。在为节点设计类时,我有两个想法:

template <typename T>
class tree_node
{
    using value_type = typename std::enable_if
        <
            std::is_same<std::string, T>::value ||
            std::is_same<int, T>::value ||
            std::is_same<float, T>::value, T
        >::type;
    value_type data;
    std::vector<??????> children;// What type must be there?
public:
...

    struct node_data {};
struct str_node: public node_data
{
    std::string data;
    str_node(std::string &str): data(str) {};
};
struct int_node: public node_data
{
    int data;
    int_node(int n): data(n) {};
};
struct float_node: public node_data
{
    float data;
    float_node(float f): data(f) {};
};
 
class tree_node
{
    std::shared_ptr<node_data> val;
    std::vector<std::shared_ptr<node_data>> children;
public:
....

对于这个问题有没有优雅的解决方案(例如,一些设计模式)?

【问题讨论】:

标签: c++ templates data-structures


【解决方案1】:

也许复合模式会帮助你:

#include <iostream>
#include <string>
#include <vector>

struct INode {
    virtual void print() = 0;
};

class CompositeNode : public INode {
private:
    std::vector<INode*> nodes;

public:
    void add(INode* node) {
        nodes.push_back(node);
    }

    void print() override {
        for(INode* node : nodes) {
            node->print();
        }
    }
};

class IntNode : public INode {
private:
    int value;
public:
    IntNode(int i) {
        value = i;
    }

    void print() override {
        std::cout << value << std::endl;
    }
};

class FloatNode : public INode {
private:
    float value;
public:
    FloatNode(float i) {
        value = i;
    }

    void print() override {
        std::cout << value << std::endl;
    }
};

class StrNode : public INode {
private:
    std::string value;
public:
    StrNode(std::string s) {
        value = s;
    }

    void print() override {
        std::cout << this->value << std::endl;
    }
};

int main () {
    StrNode s1("node1string");
    IntNode i1(1);
    FloatNode f1(1.1f);

    CompositeNode cnode1;
    cnode1.add(&s1);
    cnode1.add(&i1);
    cnode1.add(&f1);

    StrNode s2("node2string");
    IntNode i2(2);
    FloatNode f2(2.1f);

    CompositeNode cnode2;
    cnode2.add(&f2);
    cnode2.add(&i2);
    cnode2.add(&s2);

    CompositeNode cnode;
    cnode.add(&cnode1);
    cnode.add(&cnode2);

    cnode.print();
}

【讨论】:

    【解决方案2】:
    template <typename T>
    class tree_node
    {
        static_assert(std::is_same_v<int, T> || std::is_same_v<float, T>
            || std::is_same_v<std::string, T>, "...your error message");
        using value_type = T;
        value_type data;
        std::list<std::shared_ptr<value_type>> children;
       //...
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 2020-12-31
      • 1970-01-01
      相关资源
      最近更新 更多