I've been over the documentation (https://www.boost.org/doc/libs/1_75_0/libs/graph/doc/using_adjacency_list.html) here and several stack overflow pages for two hours and am not making any forward progress here at all. I have a graph where edges have both distance and number of potholes (vehicle breaks after hitting 3 potholes), so I was thinking I would use a custom struct and set edge properties.
Placed this above the class declaration:
struct road_details_t {
typedef boost::edge_property_tag kind;
};
struct road_info {
unsigned miles;
bool pothole;
};
typedef boost::property<road_details_t, struct road_info> RoadDetailsProperty;
EDIT: I believe this is an alternative to the above and have not had luck with it either:
namespace boost {
enum road_details_t { road_details };
BOOST_INSTALL_PROPERTY(edge, road_details);
}
The adjacency graph inside the class declaration:
typedef boost::adjacency_list<boost::listS, // store edges in lists
boost::vecS, // store vertices in a vector
boost::undirectedS
RoadDetailsProperty
>
Graph;
typedef boost::graph_traits<Graph> GraphTraits;
typedef GraphTraits::vertex_descriptor Vertex;
typedef GraphTraits::edge_descriptor Edge;
Graph roadMap;
Later in a function to add roads:
void City::addRoad(Intersection intersection1, Intersection intersection2, unsigned time, bool pothole)
{
unsigned nV = num_vertices(roadMap);
while (intersection1 >= nV)
nV = add_vertex(roadMap)+1;
while (intersection2 >= nV)
nV = add_vertex(roadMap)+1;
add_edge(intersection1, intersection2, roadMap);
So now I'm trying to put/get the road info, which has multiple errors and I've tried a lot of variations:
// get the edge
std::pair<Edge, bool> edg = edge(intersection1, intersection2, roadMap);
// get the property map for road details. ERROR: no matching function call to get()
typename property_map<Graph, road_details_t>::type
roadDetailMap = get(road_details_t(), roadMap);
// create struct from arguments passed in
struct road_info info = {time, pothole};
// attempt to add to roadDetailMap
put(roadDetailMap, edg, info);
// roadDetailMap[edg] = info; // also not working
// attempt to fetch information
cout << get(roadDetailMap, edg).miles << endl;
// cout << roadDetailMap[edg].miles << endl; // also not working
By commenting out various lines I've found the issue seems to be in how I'm getting the property map, but looking at examples online I feel like I'm doing the exact same thing they are.
The goal is ultimately just to figure out how to add the road information and how to get it later, so an entirely different approach is acceptible, what I have here is just what I've tried (unsuccessfully) but that I felt had the most promising results.
You can do as you suggest, which requires registering a property tag using
BOOST_INSTALL_PROPERTY
(see example/examples/edge_property.cpp for an example). Relevant snippet:However, since your use case is so frequent, there's already a built-in tag for any user-define struct:
vertex_bundle_t
andedge_bundle_t
:Bundled Properties
Here's a sample using that. Documentation: https://www.boost.org/doc/libs/1_75_0/libs/graph/doc/bundles.html
Live On Coliru
Prints
UPDATE: Edge Bundles
To the comments, making it an edge bundle is superficial modifications:
Live On Coliru
Printing:
For Masochists
If you insist you can of course install a property tag. It will be uncomfortable (and potentially inefficient) to get to the individual members, but you do you:
Live On Coliru
Again printing the same output.