user3049681
user3049681

Reputation: 407

TemplateClasses depending on each other

template <class NodeType, class EdgeType>
class GenericNetworkClass {
    typedef std::vector<EdgeType<NodeType>*> EdgesType;
    typedef std::vector<NodeType<EdgeType>*> NodesType;
    EdgesType EdgesList;
    NodesType NodesList;
}

template <class NodeType>
class GenericEdgeClass {
    std::vector<NodeType*> *Nodes;
    GenericNodeClass(std::vector<NodeType<GenericEdgeClass>*> *NodesPtr);
}

template <class EdgeType>
class GenericNodeClass {
    std::vector<EdgeType*> *Edges;
    GenericNodeClass(std::vector<EdgeType<GenericNodeClass>*> *EdgesPtr);
}

In simple terms I just want a NetworkClass with Template Nodes and Template Edges where

All NodeTypes are derived from GenericNodeClass and all EdgeTypes are derived from GenericEdgeClass.

Obviously what I wrote does not work. What's the right approach here?
I hope it's clear what I'm trying to do.

Thanks!

Upvotes: 1

Views: 74

Answers (1)

Lorenzo Gatti
Lorenzo Gatti

Reputation: 1270

You can deal with cyclic dependencies with forward declarations, but your templates are strange: why should you enforce a class hierarchy, running into all types of covariance trouble, when you can make the user-defined classes for edges and nodes unconstrained "payloads"?

template <typename EdgeData, typename NodeData> class Edge;    
template <typename EdgeData, typename NodeData> class Node;

template <typename EdgeData, typename NodeData> class Edge{
    std::vector<Node<EdgeData, NodeData>*> *Nodes;
    EdgeData data;
    public:
    Edge(std::vector<Node<EdgeData, NodeData>*>  *NodesPtr, EdgeData & data);
    EdgeData getData();
    void addNode(Node<EdgeData, NodeData> & node);
    ...
}
template <typename EdgeData, typename NodeData> class Node{
    std::vector<Edge<EdgeData, NodeData>*> *Edges;
    NodeData data;
    public:
    Node(std::vector<Edge<EdgeData, NodeData>*>  *EdgesPtr, NodeData & data);
    NodeData getData();
    void addEdge(Edge<EdgeData, NodeData> & edge);
    ...
}
template <typename EdgeData, typename NodeData> class Hypergraph{
    private:
    std::vector<Edge<EdgeData, NodeData>*> edgesList;
    std::vector<Node<EdgeData, NodeData>*>  nodesList;
    ...
}

Better yet, exploit symmetry to reduce Edge and Node to a single class:

template <typename OwnData, typename DualData> class Entity{
    std::vector<Entity<DualData, OwnData>*> *duals;
    OwnData data;
    public:
    Entity(std::vector<Entity<DualData, OwnData>*>  *duals, OwnData & data);
    OwnData getData();
    void addDual(Entity<DualData, OwnData> & dual);
    ...
}
template <typename EdgeData, typename NodeData> class Hypergraph{
    private:
    std::vector<Entity<EdgeData, NodeData>*> edgesList;
    std::vector<Entity<NodeData, EdgeData>*>  nodesList;
    ...
}

Upvotes: 1

Related Questions