5

ジェネリック プログラミングでは、アルゴリズムがコンテナーから分離されていることを理解しています。したがって、一般的なアルゴリズムをインスタンス メソッドとして実装しても意味がありません (同じアルゴリズムが複数の具象クラスで機能する必要があります。クラスの数が指数関数的に増加するため、それらすべてを 1 つの 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 に答える