我在使用 Boost 图形库的邻接列表时遇到问题。这似乎是一个循环依赖问题:
我有一个使用某个类 A 的模板的 typedef T。另外,A 存储了一个指向 T 类型对象的指针。现在编译器告诉我,T 没有命名类型。
以下是我的更具体文件的摘录:
//graphdefinitions.hpp
#include "lane.hpp"
#include "tie.hpp"
typedef boost::adjacency_list<boost::listS, boost::listS,
boost::directedS, Tie, Lane> Map;
typedef boost::graph_traits<Map>::edge_descriptor edge_descriptor;
//lane.hpp
#include "graphdefinitions.hpp"
class Lane {
...
edge_descriptor *left, *right;
};
//tie.hpp
//no important includes here
class Tie {
...
};
如何解决此依赖性/包含顺序问题?
另一个编辑:
我只是想到,edge_descriptor 的类型可能是像 int 这样的原始类型。这本来可以解决问题,因为我可以用普通的 int 变量替换 Lane 的 edge_descriptors,从而可以删除在 tie.hpp 中包含 graphdefinitions.hpp。不幸的是我的想法很糟糕,我必须找到另一个解决方案。 Edge_descriptor 类型的存在似乎是有原因的......
I have a problem with using the adjacency-list of the Boost Graphics Library. It seems to be a circular dependency problem:
I have a typedef T of a template which uses some class A. Additionally A stores a pointer to an object of type T. Now the compiler tells me, that T does not name a type.
Here are excerptions of my more concrete files:
//graphdefinitions.hpp
#include "lane.hpp"
#include "tie.hpp"
typedef boost::adjacency_list<boost::listS, boost::listS,
boost::directedS, Tie, Lane> Map;
typedef boost::graph_traits<Map>::edge_descriptor edge_descriptor;
//lane.hpp
#include "graphdefinitions.hpp"
class Lane {
...
edge_descriptor *left, *right;
};
//tie.hpp
//no important includes here
class Tie {
...
};
How do I solve this dependency / inclusion-order problem?
ANOTHER EDIT:
I just had the idea that the type of an edge_descriptor might be a primitive one like int. That would have solved the problem because I would have been able to replace the edge_descriptors of Lane by plain int-variables and thus could have removed the inclusion of graphdefinitions.hpp inside tie.hpp. Unfortunately my idea was cra* and I have to find another solution. Edge_descriptor types seem to be there for a reason...
发布评论
评论(4)
BGL 中有一个没有详细记录的特征类,它可以为
adjacency_list
图提供顶点和边描述符类型,而无需知道属性类型。它专为您所拥有的用例而设计。查看 http:// 的“关联类型”部分www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html 并注意vertex_descriptor
和edge_descriptor
有两个定义;您可以在属性包的定义中使用来自adjacency_list_traits
的版本,而不会导致循环定义。There is a not-well-documented traits class in BGL that gives the vertex and edge descriptor types for an
adjacency_list
graph without needing to know the property types. It is designed for exactly the use case you have. Look in the "Associated Types" section of http://www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html and notice that there are two definitions forvertex_descriptor
andedge_descriptor
; you can use the versions that come fromadjacency_list_traits
in the definitions of your property bundles without causing a circular definition.您已循环包含标题。车道包括图形定义,车道包括图形定义,等等。这就是你的问题的原因。
编辑:我意识到OP中已经提到了这一点。这个问题的解决方案是PIMPL。
编辑:我实际上要做的是将 typedef 放在 Lane 类中。这应该以最巧妙的方式解决问题。
You have circularly included headers. Lane includes graphdefinitions, which includes lane, which includes graphdefinitions, etc. This is the cause of your problem.
Edit: I realized this was already mentioned in the OP. The solution to this problem is PIMPL.
Edit: What I would actually do is put the typedef inside the Lane class. That should solve the problem in the neatest way.
我真的不认为你需要这段代码有什么特别的。您必须确保图中使用的类型的定义已声明(而不仅仅是前向声明)。
I really don't think you need anything special about this code. You have to make sure the definitions of the types used in the graph are declared (not only forward-declared).
@DeadMG:我现在使用了类似 PIMPL 的方法,我认为这解决了我的问题。
那么我做了什么?
我将 Lane-class 更改为如下所示:
LaneSide-class 实际上只是一个间接寻址,并保存我无法在 Lane.hpp 内转发声明的值的类型,如下所示:
这似乎欺骗了编译器正如我的意图。所以感谢 DeadMG 的提示。我想知道的是:是否也可以将 LaneSide 对象存储在 Lane 类中,而不是作为指针,而是作为真实对象?我首先尝试了这个,但编译器抱怨这个构造。我还想知道是否有办法避免额外的内存消耗。当我的图表变得足够大时,这最终可能会变得相关。
@DeadMG: I used a PIMPL-like approach now and I think that this solved my problem.
So what did I do?
I changed my Lane-class to look this way:
And the LaneSide-class which is practically just an indirection and holds the type of value that I could not forward declare inside of lane.hpp, looks this way:
This seems to trick the compiler as I intended to. So thank you for the hint DeadMG. What I was wondering: Is it also possible to store a LaneSide-object inside of the Lane-class not as a pointer but rather as a real object? I tried this first but the compiler complained about the construction. And I'm also wondering whether there might be a way to avoid the additional memory consumption. When my graph gets big enough this might eventually become relevant.