话虽如此,我的库以以下方式进行模板化:
class edge { ... };
template <class edge_T>
class node { ... };
template <class edge_T, class node_T>
class graph { ... };
我正在使用从边缘或节点派生的类创建更复杂的图表,因此加权边缘类将会很简单。
template <class T>
class weighted_edge : public edge {
public:
T weight;
...
};
现在的问题是我想在这个结构上实现一个算法,计算两个顶点之间的最短距离。我可以很容易地编写两个算法,一个用于加权边,另一个用于非加权边,但改变很小: 一个会访问
weighted_edge
(或派生类)的成员字段,而另一个则假定单位权重。是否有一种方法可以这样做,以便我可以只有一个代码片段来处理这两种情况?
一种解决方案是使用成员函数
edge::get_weight()
返回权重(或在非加权情况下返回'1'),但这会强制我为边缘类使用特定的非加权类型,所以它看起来有些奇怪。我的意思是,模板需要这样:template <class T>
class edge {
public:
...
virtual T get_weight(void) { return T(1); }
}
这并不是很友好的用户界面,或者至少会让人感到困惑,因为你不希望涉及任何权重。
BGL使用get()
函数来获取权重;我可以编写一个函数,根据edge_T
返回1或weight
,但我的担心是当从edge
或weighted_edge
派生出新类时会发生什么?如果有人写:
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); }
如果传递一个派生类,会发生什么?C++是否有机制可以选择这两个基类中更接近的一个?