我正在尝试创建一个基于对象模板的通用图形结构,但在我的设计中,我遇到了一个可能的循环依赖,我不知道该如何避免。
我按如下方式定义顶点和边类:
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中存储指向它们的指针来跟踪附加到节点的内边和外边。
在edge对象中,我保留2个引用,表示源和目标顶点。
如果我要填写顶点模板参数,我需要知道边缘的类型。为了知道我需要知道的关于顶点类型的边的类型。
知道如何解决这个问题吗?
答案 0 :(得分:1)
您可以在使用之前预先宣布一个类来解决循环依赖,如下所示:
class basic_vertex;
答案 1 :(得分:1)
无论是否模板,它与类的循环依赖性问题相同。你的一个类必须能够只使用指针/ ref到另一个类。 前向声明类Edge; 在basic_vertex中使用Edge * 在Edge
中使用basic_vertex答案 2 :(得分:1)
有一种解决方案可以解决类模板之间的相互依赖关系。但在考虑它之前,我经常问自己:“我不应该把它解耦吗?”实际上,这可能是一个糟糕的设计。但有时,它是模型的一部分。你的情况就是一个例子。
解决方案基于概念级别的解耦,并引入一个中间模板类型,它将嵌入并知道两种类型(顶点和边缘)a并打破循环。
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;
}
您可以在those very good lecture notes about advanced C++ technics找到解决方案的详尽说明。