问题
This question is about boost::graph and how to handle properties associated to vertices (and/or edges). I am quite confused about handling this, but I suspect it could be a template-related issue.
Let's say I have this graph definition:
struct myVertex_t {
int color;
};
typedef boost::adjacency_list<
boost::vecS, // edge container
boost::vecS, // vertex container
boost::undirectedS, // type of graph
myVertex_t, // vertex properties
boost::property< // edge properties
boost::edge_color_t, // ???
boost::default_color_type // enum, holds 5 colors
>
> myGraph_t;
AFAIK, this way of storing properties for vertices is called "bundle properties" and seems to be a third way of storing this information, although it is said in the manual that:
There are two kinds of graph properties: interior and exterior.
Back to my main question. Now, I can instanciate and printout a graph using the "dot" format this way:
int main()
{
myGraph_t g;
boost::add_edge(0, 1, g);
boost::dynamic_properties dp;
dp.property("color", boost::get( &myVertex_t::color, g ) );
dp.property("node_id", boost::get( boost::vertex_index, g ) );
boost::write_graphviz_dp( std::cout , g, dp);
}
Online here
This is based on this answer in a similar question, and compiles fine.
Now I want to separate the printing in a separate function, so I write the same code in a templated function, just replacing concrete types with template type arguments:
template<typename graph_t, typename vertex_t>
void RenderGraph( const graph_t& g )
{
boost::dynamic_properties dp;
dp.property( "color", boost::get( &vertex_t::color, g ) );
dp.property( "node_id", boost::get( boost::vertex_index, g ) );
boost::write_graphviz_dp( std::cout, g, dp );
}
int main()
{
myGraph_t g;
boost::add_edge(0, 1, g);
RenderGraph<myGraph_t,myVertex_t>( g );
}
But this does not compile:
property_map.hpp:361:44: error: assignment of read-only location ...
Any ideas what I did wrong ?
回答1:
property_map.hpp:361:44: error: assignment of read-only location ...
Yeah, sadly the fact that g
is const there makes the default property
factory function illegal. Dynamic properties are constructed in a writable way if the model allows it:
Requirements:
PropertyMap
must model Readable Property Map or Read/Write Property Map.
Because the property map is writable, the dynamic property compiles the writing branch too.
You'd have to take the argument as non-const or manually override the Property traits for the underlying maps (see the comments here (Cut set of a graph, Boost Graph Library) for an example).
You might consider reporting this as a usability issue, as logically, the properties should be const there.
来源:https://stackoverflow.com/questions/34160290/boostgraph-compilation-issue-with-dynamic-properties-and-write-graphviz