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...
@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.
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.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).
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.