Graph: create_subgraph not defined
Hi, I've extended an adjacency list into a custom class in order to add specialized fields and convenience methods. It was working fine until I tried to call create_subgraph on it. Simplified example: #include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp> using namespace boost; class MyGraph : public adjacency_list<vecS, vecS, bidirectionalS, size_t, property<edge_index_t, std::size_t> > { }; int main(int,char*[]) { MyGraph g; g.create_subgraph(); return 0; } This gives a compiler error: mygraph.cpp:12: error: ‘class MyGraph’ has no member named ‘create_subgraph’ I've no idea why this is giving me an error. Any suggestions? Thanks, Trevor
On Wed, 23 Jun 2010, Trevor Harmon wrote:
Hi,
I've extended an adjacency list into a custom class in order to add specialized fields and convenience methods. It was working fine until I tried to call create_subgraph on it. Simplified example:
#include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp>
using namespace boost;
class MyGraph : public adjacency_list<vecS, vecS, bidirectionalS, size_t, property<edge_index_t, std::size_t> > { };
int main(int,char*[]) { MyGraph g; g.create_subgraph(); return 0; }
This gives a compiler error:
mygraph.cpp:12: error: ‘class MyGraph’ has no member named ‘create_subgraph’
I've no idea why this is giving me an error. Any suggestions? Thanks,
Is there a create_subgraph member mentioned in the documentation? Are you sure that it is not a free (non-member) function rather than a method? -- Jeremiah Willcock
On Jun 24, 2010, at 6:50 AM, Jeremiah Willcock wrote:
Is there a create_subgraph member mentioned in the documentation?
Yes: http://www.boost.org/doc/libs/1_31_0/libs/graph/doc/subgraph.html It is also used in the subgraph.cpp example.
Are you sure that it is not a free (non-member) function rather than a method?
Yes, it is used as a member function in the documentation and example code: typedef subgraph< adjacency_list > > Graph; Graph G0(6); ..... Graph& G1 = G0.create_subgraph(); Trevor
On Thu, 24 Jun 2010, Trevor Harmon wrote:
On Jun 24, 2010, at 6:50 AM, Jeremiah Willcock wrote:
Is there a create_subgraph member mentioned in the documentation?
Yes:
http://www.boost.org/doc/libs/1_31_0/libs/graph/doc/subgraph.html
It is also used in the subgraph.cpp example.
Are you sure that it is not a free (non-member) function rather than a method?
Yes, it is used as a member function in the documentation and example code:
typedef subgraph< adjacency_list > > Graph; Graph G0(6); ..... Graph& G1 = G0.create_subgraph();
Note that G0 is of type subgraph<...>, not adjacency_list<...> like you were using. Could that be the issue? -- Jeremiah Willcock
On Jun 24, 2010, at 10:12 AM, Jeremiah Willcock wrote:
Note that G0 is of type subgraph<...>, not adjacency_list<...> like you were using. Could that be the issue?
Yes, that's definitely something I was doing wrong. After rereading the docs, I see now that subgraphs must be of a special subgraph class type, but I don't understand why. Conceptually speaking, I see no reason for this class to exist. For example, when implementing a generic tree structure, there's no need to have separate "Node" and "Subnode" classes; all nodes can be of type "Node". The top-level node is distinguished simply by the fact that it has no parents. For the same reason, the top-level graph in a hierarchy of graphs can have the same type as any of its children (and vice versa). The way Boost implements this concept seems overly complicated. Design issues aside, I'm now trying to modify my graph code to use subgraphs. To start off, I thought I would try changing my adjacency_list to subgraph<adjacency_list>. Theoretically, my code should still work the same way, right? But I'm getting compiler errors when calling get(). Pasted below is an example of the problem. The error is: subgraph.cpp: In function ‘int main(int, char**)’: subgraph.cpp:19: error: conversion from ‘boost ::subgraph_global_property_map <boost::subgraph<boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, boost::shared_ptr<MyVertex>, boost::property<boost::edge_index_t, size_t, boost::no_property>, boost::no_property, boost::listS> >*, boost::adj_list_edge_property_map<boost::bidirectional_tag, size_t, size_t&, size_t, boost::property<boost::edge_index_t, size_t, boost::no_property>, boost::edge_index_t>, boost::edge_index_t>’ to non-scalar type ‘boost::subgraph_global_property_map<MyGraph*, boost::adj_list_edge_property_map<boost::bidirectional_tag, size_t, size_t&, size_t, boost::property<boost::edge_index_t, size_t, boost::no_property>, boost::edge_index_t>, boost::edge_index_t>’ requested Any suggestions how to fix this? Thanks, Trevor #include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp> using namespace boost; class MyVertex { public: virtual ~MyVertex() {} }; class MyGraph : public subgraph<adjacency_list<vecS, vecS, bidirectionalS, shared_ptr<MyVertex>, property<edge_index_t, std::size_t> > > { }; typedef property_map<MyGraph, edge_index_t>::type EdgeIndexMap; int main(int,char*[]) { MyGraph g; EdgeIndexMap edgeMap = get(edge_index, g); return 0; }
On Jun 28, 2010, at 12:23 PM, Trevor Harmon wrote:
#include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp>
using namespace boost;
class MyVertex { public: virtual ~MyVertex() {} };
class MyGraph : public subgraph<adjacency_list<vecS, vecS, bidirectionalS, shared_ptr<MyVertex>, property<edge_index_t, std::size_t> > > { };
typedef property_map<MyGraph, edge_index_t>::type EdgeIndexMap;
int main(int,char*[]) { MyGraph g; EdgeIndexMap edgeMap = get(edge_index, g); return 0; }
Hmm... If I change the EdgeIndexMap typedef so that MyGraph is simply replaced by its superclass, then the code compiles. That is, I change this: typedef property_map<MyGraph, edge_index_t>::type EdgeIndexMap; to this: typedef property_map<subgraph<adjacency_list<vecS, vecS, bidirectionalS, shared_ptr<MyVertex>, property<edge_index_t, std::size_t> > >, edge_index_t>::type EdgeIndexMap; I'm afraid my Boost-fu isn't very strong. Can someone please explain this to me? Thanks, Trevor
On Jun 28, 2010, at 12:23 PM, Trevor Harmon wrote:
Design issues aside, I'm now trying to modify my graph code to use subgraphs. To start off, I thought I would try changing my adjacency_list to subgraph<adjacency_list>. Theoretically, my code should still work the same way, right? But I'm getting compiler errors when calling get().
I'm also getting compiler errors when calling add_vertex. Example: #include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp> using namespace boost; class MyGraph : public subgraph<adjacency_list<vecS, vecS, bidirectionalS, std::string, property<edge_index_t, std::size_t> > > { }; int main(int,char*[]) { MyGraph g; std::string v; add_vertex(v, g); return 0; } error: no matching function for call to ‘add_vertex(std::string&, MyGraph&)’ /Users/twharmon/Development/boost_1_43_0/boost/graph/subgraph.hpp:346: note: candidates are: typename boost::subgraph<Graph>::vertex_descriptor boost::add_vertex(typename boost::subgraph<Graph>::vertex_descriptor, boost::subgraph<Graph>&) [with G = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, std::string, boost::property<boost::edge_index_t, size_t, boost::no_property>, boost::no_property, boost::listS>] The error goes away if I take out "subgraph" or simply change the vertex type from std::string to a primitive type, such as size_t or double. So... have I completely misunderstood how to use subgraphs? Or am I encountering some sort of Boost bug? Thanks, Trevor
On Jun 29, 2010, at 3:13 PM, Trevor Harmon wrote:
I'm also getting compiler errors when calling add_vertex. Example:
#include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp>
using namespace boost;
class MyGraph : public subgraph<adjacency_list<vecS, vecS, bidirectionalS, std::string, property<edge_index_t, std::size_t> > > { };
int main(int,char*[]) { MyGraph g; std::string v; add_vertex(v, g); return 0; }
I think the problem here is that I'm trying to use MutablePropertyGraph's specialization of add_vertex, which takes a property as the first parameter, while subgraph's version of add_vertex takes a descriptor as the first parameter. Therefore I can work around the problem by first adding the vertex (without any properties). I can then attach the property to the vertex in a second step. Example: #include <boost/graph/adjacency_list.hpp> #include <boost/graph/subgraph.hpp> using namespace boost; class MyGraph : public subgraph<adjacency_list<vecS, vecS, bidirectionalS, std::string, property<edge_index_t, std::size_t> > > { }; int main(int,char*[]) { MyGraph g; std::string v; graph_traits<MyGraph>::vertex_descriptor descriptor = add_vertex(g); g[descriptor] = v; return 0; } Trevor
participants (2)
-
Jeremiah Willcock
-
Trevor Harmon