5

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

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

据我通过阅读BGL 源代码可知,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;
    };
  }
}
4

2 回答 2

6

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

比如说,你想std::multimap实现这个IncidenceGraph概念。如果图形库需要source()成为成员函数,那么您将不走运,因为std::multimap没有提供。

于 2013-04-20T16:02:48.840 回答
3

在 C++ 中,应该尽可能选择非成员非友元函数。如果source可以根据设计用于操作的类的公共成员来实现,那么它应该在类之外。

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

于 2013-04-19T23:25:05.377 回答