多くの部分でメンバ関数と非メンバ関数の違いは文法的なもので、それほど重要でもないが、 にもかかわらず、人々はそれら[訳注:メンバ関数]に関する信仰を持つものらしい。 しかし、我々が自由関数を好むのには一つの技術的な理由がある。 プログラマはサードパーティに由来する型に対して、その型のソースコードや定義を変更することなく、 非メンバ関数をオーバーロードできる。 BGL ではこれがいくつかの方法で使われている。 例えば、 Stanford GraphBase と LEDA のグラフはいずれも BGL アルゴリズムで使用できる。 なぜなら stanford_graph.hpp と leda_graph.hpp でオーバーロードされているからである。 std::vector<std::list> でさえ、 vector_as_graph.hpp でオーバーロードされているので、グラフとして使う事ができる。
もちろん、メンバ関数でサードパーティ製クラスをインターフェイスに適応させる方法もある。 アダプタクラスを作成するのである。 しかし、(オーバーロード関数と比較した)アダプタクラスの短所は、 オブジェクトが BGL アルゴリズムに出入りする際に、それを実際にラップしたり アンラップしたりしなければならないことである。 とは言え、これは大きな違いではない。しかし他の強い理由が存在しない以上、 メンバ関数を選ぶには十分な理由だった。
我々が非メンバ関数を選んだ信仰上の理由は、 BGL がジェネリックなライブラリであって、 伝統的なオブジェクト指向ライブラリでないというメッセージを送るためである。 OO は 80 年代と 90 年代に一世を風靡したが、今やそれを越えていく時なのだ!
この ordered_out_edges.cpp 例で、どのようにするのか示している。
// グラフの型を定義 typedef adjacency_list<listS, listS, undirectedS, property<vertex_index_t, std::size_t>, no_property > graph_t; // グラフオブジェクトの構築 graph_t G(num_nodes); // vertex_index_property のプロパティマップを得る property_map<graph_t, vertex_index_t>::type index = get(vertex_index, G); // vertex_index プロパティの値を初期化する graph_traits<graph_t>::vertex_iterator vi, vend; graph_traits<graph_t>::vertices_size_type cnt = 0; for(tie(vi,vend) = vertices(G); vi != vend; ++vi) put(index, *vi, cnt++);
../../../boost/concept_check.hpp:209: no match for `boost::detail::error_property_not_found & == boost::detail::error_property_not_found &'あるいはこんなメッセージ:
../../..\boost/graph/depth_first_search.hpp(78) : error C2664: 'white' : cannot convert parameter 1 from 'struct boost::detail::error_property_not_found' to 'enum boost::default_color_type'その理由は、そのアルゴリズムが、グラフの頂点や辺に付随するいくつかの プロパティ(色や重みのような)が見つかることを期待しているのに、 見つからなかったためである。 グラフに内部プロパティを追加するか、さもなくばそのプロパティのための 外部プロパティマップを作成してアルゴリズムの引数としてそれを渡す 必要がある。
Japanese Translation Copyright © 2003 Kent.N
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。また、いかなる目的に対しても、その利用が適していることを関知しない。
このドキュメントの対象: Boost Version 1.29.0
最新版ドキュメント (英語)