2012-12-10 43 views
0

我想創建一個面向對象的基於模板的通用圖結構,然而在我的設計中,我遇到了一個可能的循環依賴關係,我不知道如何避免。又一個模板循環依賴問題

我定義我的頂點和邊緣類,如下所示:

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

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

在頂點I類保持由存儲指向它們一個std ::名單附到該節點的內緣部分和外邊緣的軌道。

在邊緣對象中,我保留2個引用來表示源和目標頂點。

如果我要填寫頂點模板參數,我需要知道邊緣的類型。爲了知道我需要知道的頂點類型的邊的類型。

任何想法如何解決這個問題?

+0

你能解釋你爲什麼使用模板嗎? – alestanis

+0

@alestanis:我試圖使其儘可能通用且儘可能快。 –

+0

Re *我試圖使它儘可能通用且儘可能快*:模板不是魔法編程灰塵,它使事情變得更快。就通用性而言,這聽起來像是不成熟的優化。所以再一次,你爲什麼使用模板? –

回答

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

你會發現在those very good lecture notes about advanced C++ technics解決方案的廣泛的解釋。

1

可以預先宣佈一類的使用,以解決循環依賴之前,如下所示:

class basic_vertex; 
+1

這不適用於我害怕的模板。編譯器告訴我需要指定模板參數。 –

1

無論其模板與否,它與類循環依賴的同樣的問題。你的一個類必須能夠使用一個指針/引用另一個類。 正向聲明類邊; 在basic_vertex中使用Edge * 在Edge中使用basic_vertex