У меня есть два класса, представляющих граф:
class Node {
public:
void AppendSource(Edge &Edge) { m_Sources.append(&Edge); }
void AppendSink(Edge &Edge) { m_Sinks.append(&Edge); }
QList<Edge *> &Sources() { return m_Sources; }
QList<Edge *> &Sinks() { return m_Sinks; }
QList<Edge *> const &Sources() const { return m_Sources; }
QList<Edge *> const &Sinks() const { return m_Sinks; }
protected:
QList<Edge *> m_Sources;
QList<Edge *> m_Sinks;
}; // Node
class Edge {
public:
Edge(Node &Source, Node &Sink) : m_pSource(&Source), m_pSink(&Sink) {}
Node const &Source() const { return *m_pSource; }
Node const &Sink() const { return *m_pSink; }
Node &Source() { return *m_pSource; }
Node &Sink() { return *m_pSink; }
void SetSource(Node &Source) { m_pSource = &Source; }
void SetSink(Node &Sink) { m_pSink = &Sink; }
protected:
Node *m_pSource;
Node *m_pSink;
}; // Edge
Должно быть возможно наследовать от этих классов, чтобы добавить функциональность для определенных типов графов.Следовательно, классы должны быть шаблонными классами:
template <class EDGE_TYPE>
class Node {
public:
void AppendSource(EDGE_TYPE &Edge) { m_Sources.append(&Edge); }
void AppendSink(EDGE_TYPE &Edge) { m_Sinks.append(&Edge); }
QList<EDGE_TYPE *> &Sources() { return m_Sources; }
QList<EDGE_TYPE *> &Sinks() { return m_Sinks; }
QList<EDGE_TYPE *> const &Sources() const { return m_Sources; }
QList<EDGE_TYPE *> const &Sinks() const { return m_Sinks; }
protected:
QList<EDGE_TYPE *> m_Sources;
QList<EDGE_TYPE *> m_Sinks;
}; // Node
template <class NODE_TYPE>
class Edge {
public:
Edge(NODE_TYPE &Source, NODE_TYPE &Sink) : m_pSource(&Source), m_pSink(&Sink) {}
NODE_TYPE const &Source() const { return *m_pSource; }
NODE_TYPE const &Sink() const { return *m_pSink; }
NODE_TYPE &Source() { return *m_pSource; }
NODE_TYPE &Sink() { return *m_pSink; }
void SetSource(NODE_TYPE &Source) { m_pSource = &Source; }
void SetSink(NODE_TYPE &Sink) { m_pSink = &Sink; }
protected:
NODE_TYPE *m_pSource;
NODE_TYPE *m_pSink;
}; // Edge
Но теперь, кажется, больше невозможно использовать классы без их расширения!Несколько попыток с очевидными соответствующими ошибками:
new Node(); // 'Node': use of class template requires template argument list
new Node<>(); // 'Node': too few template arguments
new Node<Edge>(); // 'Edge': unspecialized class template can't be used as a template argument for template parameter 'EDGE_TYPE', expected a real type
new Node<Edge<>>(); // 'Edge': too few template arguments
new Node<Edge<Node>>(); // 'Node': unspecialized class template can't be used as a template argument for template parameter 'NODE_TYPE', expected a real type
new Node<Edge<Node<>>>(); // 'Node': too few template arguments
Я надеялся решить эту проблему, введя значения по умолчанию для аргументов шаблона.Несколько попыток с соответствующими ошибками:
template <class EDGE_TYPE = Edge>
class Node { ... }
template <class NODE_TYPE = Node>
class Edge { ... }
new Node<>(); // 'Edge': unspecialized class template can't be used as a template argument for template parameter 'EDGE_TYPE', expected a real type
template <class EDGE_TYPE = Edge<>>
class Node { ... }
template <class NODE_TYPE = Node<>>
class Edge { ... }
new Node<>(); // recursive type or function dependency context too complex
template <class EDGE_TYPE = Edge<Node<EDGE_TYPE>>>
class Node { ... }
template <class NODE_TYPE = Node<Edge<NODE_TYPE>>>
class Edge { ... }
new Node<>(); // 'EDGE_TYPE': undeclared identifier
Как я могу сделать Node
и Edge
как непосредственно используемыми, так и расширяемыми через наследование?