My problem is as follows. I learn C ++ by writing a graph library and want to use as many common programming methods as possible; therefore, the answer to my question through “using BOOST” will not help me; in fact, I tried to look at the BOOST code to answer my question, but it was a humble experience, since I cannot even determine where certain functions are defined; just too high a level of C ++ for training at my level.
However, my library is templated as follows:
class edge { ... }; template <class edge_T> class node { ... }; template <class edge_T, class node_T> class graph { ... };
and I create more complex graphs using classes derived from edge or node, so the weighted edge class will be just
template <class T> class weighted_edge : public edge { public: T weight; ... };
Now the problem is that I want to implement an algorithm of this structure that calculates the shortest distance between two vertices. I could easily write two of them: one for weighted edges and one for unweighted ones, but the change is tiny: you could access the field of the weighted_edge element (or derived classes), and the other a unitary weight.
Is there a way to do this, so that I can only have one piece of code for both cases?
One solution is to use the member function edge::get_weight() , which will return the weight (or "1" in the unweighted case), but that would force me to use a certain type of weight for the edge class, which is unweighted, so it smells funny. I mean, the template should be
template <class T> class edge { public: ... virtual T get_weight(void) { return T(1); } }
which is not entirely user friendly or at least confusing, as you do not expect any weights to be there.
BGL uses the get() function to get the weight; I could write a function that returns 1 or weight depending on edge_T , but my concern is what happens when it comes from edge or weighted_edge ? If you write:
template <class T> inline T get_weight(edge & e) { return T(1); } template <class T> inline T get_weight(weighted_edge & e) { return T(e.weight); }
what happens if you pass a derived class? Is there a C ++ mechanism that would choose a “closer” base class from these two?