为什么Boost Graph Library的`source()`是一个全局函数?

时间:2013-04-19 22:53:44

标签: c++ generics boost boost-graph

据我所知,在通用编程中,算法与容器分离。因此,将通用算法实现为实例方法是没有意义的(相同的算法应该适用于多个具体类;我们不希望它们都从一个ABC继承,因为它会以指数方式增加类的数量)。

但是对于source()Boost Graph Library函数的情况,我不明白它为什么是全局函数而不是图类的实例方法。

据我所知,通过阅读BGL source codesource(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;
    };
  }
}

2 个答案:

答案 0 :(得分:6)

source(e, g)不是通用算法。它是接口的一部分,通常在C ++中称为概念。作为非成员函数的原因是它可以非侵入地实现。

例如,假设您希望std::multimap实现IncidenceGraph概念。如果图表库需要source()作为成员函数,那么您将失去运气,因为std::multimap没有提供。{/ p>

答案 1 :(得分:3)

在C ++中,人们应该更喜欢可以这样做的非成员非朋友功能。如果source可以根据其设计用于操作的类的公共成员来实现,那么它应该在类之外。

这与制作通用算法无关;它完全是为了减少有权访问/可能破坏类私有成员内部状态的代码量。