据我所知,在通用编程中,算法与容器分离。因此,将通用算法实现为实例方法是没有意义的(相同的算法应该适用于多个具体类;我们不希望它们都从一个ABC继承,因为它会以指数方式增加类的数量)。
但是对于source()
中Boost Graph Library函数的情况,我不明白它为什么是全局函数而不是图类的实例方法。
据我所知,通过阅读BGL source code,source(e, g)
需要知道图表的实现细节和传递给它的边缘对象;只知道他们的接口是不够的。
所以source()
不是通用算法。换句话说,它需要知道图形实例的具体类。那么为什么不把它作为实例方法放在同一个类中呢?它不是比制作一个需要为每个被调用的类定制的全局函数更清晰/更少混淆吗?
更新
相关的源代码:
// dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
template <class Directed, class Vertex,
class OutEdgeListS,
class VertexListS,
class DirectedS,
class VertexProperty,
class EdgeProperty,
class GraphProperty, class EdgeListS>
inline Vertex
source(const detail::edge_base<Directed,Vertex>& e,
const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
{
return e.m_source;
}
namespace boost {
namespace detail {
template <typename Directed, typename Vertex>
struct edge_base
{
inline edge_base() {}
inline edge_base(Vertex s, Vertex d)
: m_source(s), m_target(d) { }
Vertex m_source;
Vertex m_target;
};
}
}
答案 0 :(得分:6)
source(e, g)
不是通用算法。它是接口的一部分,通常在C ++中称为概念。作为非成员函数的原因是它可以非侵入地实现。
例如,假设您希望std::multimap
实现IncidenceGraph
概念。如果图表库需要source()
作为成员函数,那么您将失去运气,因为std::multimap
没有提供。{/ p>
答案 1 :(得分:3)
在C ++中,人们应该更喜欢可以这样做的非成员非朋友功能。如果source
可以根据其设计用于操作的类的公共成员来实现,那么它应该在类之外。
这与制作通用算法无关;它完全是为了减少有权访问/可能破坏类私有成员内部状态的代码量。