Don't try to do hybrids. They're difficult to implement and maintain.
O_o
A hybrid approach is easier to implement and maintain when correctly approached than forcing validation on the implementation or the clients to get the requested behavior.
The problem, once again, is trying to accomplish polymorphic collections and homogeneous collections with the same code.
The solution is exceedingly simple: use a homogeneous collection to implement the graph algorithms while still allowing the client to graph polymorphic objects as requested by moving the conditional behavior (The only conditional behavior discussed so far within the thread is one regarding the filtering of the dynamic type of particular nodes before a collection is returned to a client, but you can certainly also move other conditional behavior.) into separate code.
The suggested approach would allow the code to hit every note requested.
Rather than
Code:
template<typename Node_t>
class XGraph
{
static_assert(std::is_base_of<BaseNode, Node_t>::value, "Node_t must be a type derived from BaseNode.");
std::vector<Node_t*> m_Nodes;
// ...
std::vector<Node_t*> GetNeighbours(Node_t* Node);
};
or
Code:
class XGraph
{
std::vector<BaseNode*> m_Nodes;
// ...
std::vector<BaseNode*> GetNeighbours(BaseNode* Node);
};
you choose
Code:
template<typename TypeStoredWithinNode>
class XNode
{
TypeStoredWithinNode m;
};
template<typename TypeStoredWithinNode>
class XGraph
{
static_assert(std::is_base_of<BaseNode, Node_t>::value, "Node_t must be a type derived from BaseNode.");
std::vector<XNode<TypeStoredWithinNode>> m_Nodes;
// ...
std::vector<XNode<TypeStoredWithinNode>> GetNeighbours(Node_t* Node);
template <typename TypeStoredWithinNodeFilter> std::vector<XNode<TypeStoredWithinNode>> GetNeighbours(Node_t* Node, TypeStoredWithinNodeFilter Filter)
{
std::vector<XNode<TypeStoredWithinNode>> source(GetNeighbours(Node));
std::vector<XNode<TypeStoredWithinNode>> destination;
std::copy_if(source.begin(), source.end(), std::back_inserter(destination, Filter));
return destination;
}
};
As I have already offered, the behavior of the graphing algorithms as conditioned upon the characteristics of the types graphed do not require inheritance-based polymprhisms.
Soma