0

オブジェクト指向のテンプレート ベースの一般的なグラフ構造を作成しようとしていますが、私の設計では、回避方法がわからない可能性のある循環依存関係に遭遇しました。

頂点とエッジのクラスを次のように定義します。

template <class label_type, class edge_type>
class basic_vertex { .. }

template <class vertex_type, class weight_type = std::int32_t>
class basic_edge { .. }

頂点クラスでは、std::list にポインターを格納することで、ノードに接続された内側のエッジと外側のエッジを追跡します。

エッジ オブジェクトでは、ソース頂点と宛先頂点を示す 2 つの参照を保持します。

頂点テンプレート パラメーターを入力する場合は、エッジのタイプを知る必要があります。エッジのタイプを知るには、頂点のタイプを知る必要があります。

これを解決する方法はありますか?

4

3 に答える 3

1

次のように、循環依存を解決するために使用する前に、クラスを事前にアナウンスできます。

class basic_vertex;
于 2012-12-10T12:22:29.000 に答える
1

テンプレートであろうとなかろうと、クラスとの循環依存の問題は同じです。クラスの 1 つは、他のクラスへのポインタ/参照だけで動作できる必要があります。クラス Edge を前方宣言します。Basic_vertex で Edge* を使用 Edge で basic_vertex を使用

于 2012-12-10T21:10:40.693 に答える
1

クラス テンプレート間の相互依存関係を解決するソリューションがあります。しかし、それを検討する前に、私は通常、「切り離すべきではないか」と自問する必要があります。確かに、それは悪い設計である可能性があります。ただし、モデルの一部である場合もあります。あなたのケース、グラフは一例です。

このソリューションは、概念レベルでのデカップリングに基づいており、両方のタイプ (頂点とエッジ) を埋め込んで認識し、ループを解消する中間テンプレート タイプを導入します。

template <typename T_graph, typename T_label>
struct vertex_tmpl {
    typedef typename T_graph::edge_t edge_t;
    edge_t* edge;
    // .... maybe some more edges ....
};

template <typename T_graph, typename T_weight>
struct edge_tmpl {
    typedef typename T_graph::vertex_t vertex_t;
    vertex_t* vertex;
};

template < template <typename, typename> class T_vertex,
           template <typename, typename> class T_edge,
           typename T_weight = int,
           typename T_label = int >
struct graph_tmpl {
    typedef graph_tmpl< T_vertex, T_edge> self_t;
    typedef T_vertex<self_t, T_label> vertex_t;
    typedef T_edge<self_t, T_weight> edge_t;
};

int main() {
    typedef graph_tmpl< vertex_tmpl, edge_tmpl> graph_t;
    typedef typename graph_t::edge_t basic_edge;
    typedef typename graph_t::vertex_t basic_vertex;

    basic_edge edge;
    basic_vertex vertex;
    vertex.edge = &edge;
    edge.vertex = &vertex;
}

http://ideone.com/FrBqcb

高度な C++ テクニックに関する非常に優れたレクチャー ノートで、ソリューションの詳細な説明を見つけることができます。

于 2013-12-28T20:47:19.497 に答える