C++ 为什么Boost图形库';s`source()`是全局函数吗?

C++ 为什么Boost图形库';s`source()`是全局函数吗?,c++,generics,boost,boost-graph,C++,Generics,Boost,Boost Graph,我知道在泛型编程中,算法与容器是解耦的。因此,将泛型算法作为实例方法来实现是没有意义的(相同的算法应该适用于多个具体类;我们不希望让它们都从一个ABC继承,因为这样会使类的数量成倍增加) 但是对于中的函数,我不理解为什么它是一个全局函数而不是一个图类的实例方法 通过阅读,源代码(例如)需要知道传递给它的图形和边对象的实现细节;仅仅知道它们的接口是不够的 因此source()不是通用算法。换句话说,它需要知道图形实例的具体类。那么为什么不把它作为实例方法放在同一个类中呢?与创建一个需要根据调用的每

我知道在泛型编程中,算法与容器是解耦的。因此,将泛型算法作为实例方法来实现是没有意义的(相同的算法应该适用于多个具体类;我们不希望让它们都从一个ABC继承,因为这样会使类的数量成倍增加)

但是对于中的函数,我不理解为什么它是一个全局函数而不是一个图类的实例方法

通过阅读,
源代码(例如)
需要知道传递给它的图形和边对象的实现细节;仅仅知道它们的接口是不够的

因此
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;
    };
  }
}
//dwa 09/25/00-需要更加明确,这样反向图才能工作。
模板
内联顶点
来源(施工详图::边缘基础和e,
常量邻接列表&)
{
返回e.m_源;
}
名称空间提升{
名称空间详细信息{
模板
结构边库
{
内联边_base(){}
内联边_基(顶点s、顶点d)
:m_源(s),m_目标(d){}
顶点m_源;
顶点m_目标;
};
}
}

在C++中,人们应该更喜欢非成员非朋友函数,在这里可以这样做。如果
source
可以在其设计用于操作的类的公共成员中实现,则它应该在类之外

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

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


例如,您希望
std::multimap
实现
IncidenceGraph
概念。如果图形库要求
source()
作为一个成员函数,那么您就不走运了,因为
std::multimap
没有提供成员函数。

没有理由源(a,b)不能根据其参数的类型进行专门化。并非所有内容都必须是成员函数。一些自由函数可以被视为类接口的一部分。此外,将source()用作垫片可能会很有用。没有阅读和理解代码(在链接的2次点击中是不可访问的),我不能真正告诉你,因为我不使用图形库,但它们可能是需要考虑的事情。或者,直接邮寄给BGL开发人员,询问他们的设计决策。我想这有一个很好的理由,这有一个让你烦恼的理由吗?@BenjaminLindley,谢谢-这本书读得很好。@Pete我觉得很奇怪,
edge\u base
公开了它的
m\u源代码
成员。如果它是其公共界面的一部分,为什么即使两者都具有
source
功能,也可以让人们直接访问
m_source
。我会写信给开发人员,我只是觉得我可能因为缺少对C++的熟悉而错过了一些东西。谢谢。它实际上是一个非友元函数,因为它访问的对象只有公共成员(实际上,它是一个结构)。然而,我不明白为什么这些成员会被公开。请参阅。@max它取决于类/结构是否旨在防止违反不变量。在这种情况下,结构持有的两个顶点可能没有必须保持的实际不变量(即,如果它们是相同的顶点,则是合法的?)。如果没有不变量,那么为什么成员需要是私有的?一致性?或者,BGL开发人员可能不会费心编写所有的粘合代码。我相信这就是原因。但是为什么从
multimap
继承并添加
source
作为成员函数是不好的呢?@max这并不坏,它只是不能解决使
std::multimap
成为
IncidenceGraph
的问题。如果我理解正确,您正在谈论以下情况。假设给我一个对象
data
,它是
std::multimap
的一个实例。我想将
数据
解释为一个图形,方法是将键值视为图形顶点,将其映射值视为邻接列表。我可以理解为什么非成员函数方法在这里非常有效。但是,如果我想将
数据
视为使用两种不同解释的图形,会发生什么?然后我需要编写两组非成员函数。如何避免它们相互碰撞?BGL不要求它们都在同一名称空间中吗?