Home > Enterprise >  Multiple data types within one vector of pointers using templates
Multiple data types within one vector of pointers using templates

Time:12-31

I have two classes seen below,

template <typename T> class node   {
public:
    int NodeID;//ID used to identify node when inserting/deleting/searching
    T data;//generic data encapsulated in each node.
    std::vector<node*> children;//child nodes, list of ptrs
    std::vector<node*> parents;//parent nodes list of ptrs
};

template<typename T> class DAG {//Class for the graph

    std::vector<node<T>*> Nodes;//Vector of node ptrs, this is how we define a DAG;
}

I was wondering whether its possible using templates to have the vector of nodes contain nodes of multiple types? Something like this.

std::vector<node*> Nodes = {node<int>*,node<string>*, ...}

CodePudding user response:

I suggest that you use polymorphism and create a non-template base class:

struct nodebase {
    nodebase(int id) : NodeID{id} {}
    virtual ~nodebase() = default; // to be able to delete via base class pointer

    virtual void print(std::ostream& os) const {
        os << NodeID;
    }

    int NodeID;  // ID used to identify node when inserting/deleting/searching

    std::vector<std::unique_ptr<nodebase>> children; // child nodes, list of ptrs
    std::vector<nodebase*> parents;  // parent nodes list of ptrs
};

// to be able to print all nodes, calls the overridden `print` method:
std::ostream& operator<<(std::ostream& os, const nodebase& nb) {
    nb.print(os);
    return os;
}

With that base class, your node<T> could look like this:

template <typename T>
class node : public nodebase {
public:
    // constructor taking `id`   the arguments needed for `T`:
    template<class... Args>
    node(int id, Args&&... args) : nodebase{id}, data{std::forward<Args>(args)...} {}

    void print(std::ostream& os) const override {
        nodebase::print(os);
        os << ',' << data;
    }

    T data;  // generic data encapsulated in each node.
};

And you could use it like so:

int main() {
    std::vector<std::unique_ptr<nodebase>> Nodes;

    Nodes.emplace_back(std::make_unique<node<int>>(1, 12356));
    Nodes.emplace_back(std::make_unique<node<std::string>>(2, "Hello world"));

    for(auto& ptr : Nodes) {
        std::cout << *ptr << '\n';
    }
}

Output:

1,12356
2,Hello world
  • Related