[BGL] How to use an array in bundled property?
I defined an double array inside bundled vertex property, and have trouble finding ways of accessing it. Neither can I find any where in the document an example on it. Your input will be much appreciated! my graph is defined as follows: struct Node { double mode[3]; // this is hard to access }; struct Edge { double nPixels; unsigned short nTh; //no problem access them }; typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, Node, Edge> Graph; Graph colGraph; I have no problem with accessing the 'nPixels' in Edge property, boost::property_map<Graph, double Edge::*>::type ew = get(&Edge::nPixels, *colGraph);//edge weight But I am in a great deal of trouble finding ways of accessing 'mode' in Node property. compiler error here: boost::property_map<Graph, double Node::*>::type nm = get(&Node::mode, *colGraph);//node mode error message is : //---------------------------------------------------- c:\...\xxx.cpp(236) : error C2440: 'initializing' : cannot convert from 'boost::property_map<Graph,Property>::type' to 'boost::bundle_property_map<Graph,Descriptor,Bundle,T>' with [ Graph=boost::adjacency_list<boost::vecS,boost::vecS,boost::bidirectionalS,Node, Edge>, Property=double (Node::* )[3] ] and [ Graph=Graph, Descriptor=boost::property_map<Graph,double Node::* >::descriptor, Bundle=Node, T=double ] No constructor could take the source type, or constructor overload resolution was ambiguous //---------------------------------------------------- neither the following works(I added '[3]' in the parameter list): boost::property_map<Graph, double Node::*[3]>::type nm = get(&Node::mode, *colGraph);//node mode This time errors are raised in the 'property.hpp' file, they are: //---------------------------------------------------- c:\Boost\include\boost-1_33_1\boost\pending\property.hpp(40) : error C2825: 'PropertyTag::kind': cannot form a qualified name c:\Boost\include\boost-1_33_1\boost\graph\properties.hpp(198) : see reference to class template instantiation 'boost::property_kind<PropertyTag>' being compiled with [ PropertyTag=double Node::* [3] ] c:\shufei\VCProjects\edison\segm\GA.cpp(236) : see reference to class template instantiation 'boost::property_map<Graph,Property>' being compiled with [ Graph=Graph, Property=double Node::* [3] ] c:\Boost\include\boost-1_33_1\boost\pending\property.hpp(40) : error C2039: 'kind' : is not a member of 'operator``global namespace''' c:\Boost\include\boost-1_33_1\boost\pending\property.hpp(40) : error C2146: syntax error : missing ';' before identifier 'type' c:\Boost\include\boost-1_33_1\boost\pending\property.hpp(40) : error C2955: 'boost::type' : use of class template requires template argument list c:\Boost\include\boost-1_33_1\boost\type.hpp(14) : see declaration of 'boost::type' c:\Boost\include\boost-1_33_1\boost\pending\property.hpp(40) : fatal error C1903: unable to recover from previous error(s); stopping compilation //---------------------------------------------------- thanks, Shufei
Hi Shufei, On 3/1/07, Shufei Fan <fansf@hotmail.com> wrote:
I defined an double array inside bundled vertex property, and have trouble finding ways of accessing it.
Neither can I find any where in the document an example on it. Your input
will be much appreciated!
Don't worry, there seems to be no example ;) Second, there seems to be no way of accesssing it. But this is what I did: [snipped declarations] struct Node
{ // this is hard to access double mode[3]; int test; };
compiler error here: boost::property_map<Graph, double Node::*>::type nm = get(&Node::mode, *colGraph);//node mode
I think the type of the property map should be: boost::property_map<Graph, double (Node::*) [3]>::type (the brackets around the pointer to member are important) [snipped other errors] But with that property_map declaration the specialization for the (bundled) property map doesn't work. So I wrote a new one for arrays. I'm not really sure if that is the correct way, but at least it works ;) Maybe we can get Doug (who made the bundled properties) to comment on this. Your complete example: #include <iostream> #include <boost/graph/adjacency_list.hpp> struct Node { // this was hard to access double mode[3]; int test; }; struct Edge { //no problem access them double nPixels; unsigned short nTh; }; //new specialization of property_map for bundles with arrays namespace boost{ template <typename Graph, typename T, typename Bundle, unsigned int Size> struct property_map<Graph, T (Bundle::*) [Size]> { private: typedef graph_traits<Graph> traits; typedef typename Graph::vertex_bundled vertex_bundled; typedef typename Graph::edge_bundled edge_bundled; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), typename traits::vertex_descriptor, typename traits::edge_descriptor>::type descriptor; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), vertex_bundled, edge_bundled>::type actual_bundle; public: typedef bundle_property_map<Graph, descriptor, actual_bundle, T[Size]> type; typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T[Size]> const_type; }; }; int main(){ using namespace boost; using namespace std; typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,Node, Edge> Graph; Graph colGraph(3); colGraph[vertex(0, colGraph)].mode[0] = 1.01; typedef double (Node::* ptrToNodeMode)[3]; boost::property_map<Graph, ptrToNodeMode>::type nm = get(&Node::mode, colGraph); Graph::vertex_iterator vit,vend; for(tie(vit, vend) = vertices(colGraph); vit != vend; ++vit){ for(unsigned int i = 0; i < 3; ++i){ cout << nm[*vit][i] << endl; } } }
Using the replied method, my initial difficulty was resolved. However, when I introduce more properties into my vertex bundle, I am baffled again. I figure some fundamental understanding of bundle property is necessary for me(It is appreciated, if someone can hint on this) This time, my graph definition is: ///////////////////////////////////////////////////////////////////// struct Node { int count; int matched_to; std::vector<int> absorb; double mode[3]; double center[2]; int extremes[4]; }; struct Edge { double maxBoundaryPoints; double eWeight; unsigned short nTh; }; //the following provided by Stephan //For accessing Node::mode[3], etc: //pointer to Node-Mode //new specialization of property_map for bundles with arrays namespace boost{ template <typename Graph, typename T, typename Bundle, unsigned int Size> struct property_map<Graph, T (Bundle::*) [Size]> { private: typedef graph_traits<Graph> traits; typedef typename Graph::vertex_bundled vertex_bundled; typedef typename Graph::edge_bundled edge_bundled; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), typename traits::vertex_descriptor, typename traits::edge_descriptor>::type descriptor; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), vertex_bundled, edge_bundled>::type actual_bundle; public: typedef bundle_property_map<Graph, descriptor, actual_bundle, T [Size]> type; typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T [Size]> const_type; }; }; typedef boost::adjacency_list< boost::listS, boost::listS, boost::bidirectionalS, boost::property<vertex_index_t, int, Node>, Edge> Graph; //////////////////////////////////////////////////////////////////////////// In my appliication, I defined a class GA, containing pointer of type Graph. And my compiling error comes from constructor of GA, as detailed follows: /////////////////////////////////////////////////////////////////// class GA { .... Graph *rowGraph; .... GA(){};//compiling error occurs here GA(*, *, *); .... } GA::GA(*, *, *) {//compiling error occurs here, too } /////////////////////////////////////////////////////// And my compiling error comes from constructor of GA, but it is clearly related from above work-around for accessing bundled array. Any clues? c:\shufei\VCProjects\edison\segm\GA.h(182) : error C2512: 'boost::bundle_property_map<Graph,Descriptor,Bundle,T>' : no appropriate default constructor available with [ Graph=Graph, Descriptor=boost::property_map<Graph,int Node::* >::descriptor, Bundle=Node, T=int ] Thanks
Hi Shufei, On 4/9/07, Shufei Fan <fansf@hotmail.com> wrote:
Using the replied method, my initial difficulty was resolved. However, when I introduce more properties into my vertex bundle, I am baffled again.
I cannot reproduce your error here. Can you please extract a small testcase? Cheers, Stephan
In response to Stephan's requests for detail(sorry, I cannot find stephan's reply on 'gmane.org', though i saw it on 'boost.org'. So I have to reply to my own topic instead). Thanks Stephan! I found out later that a member defined in my class GA was causing the compiling error: class GA{ //data members Graph* rg;//deine a pointer to Graph object ... //after commenting out this line, it compiles boost::property_map<Graph, int Node::*>::type nmt;//define a pointer to one of Node's property ... } I still donot know why, but I think it might be that member variable declaration cannot be resolved, so it cannot be class member variable? Thanks, Shufei
Hi Shufei, On 4/10/07, Shufei Fan <fansf@hotmail.com> wrote: [snip]
I found out later that a member defined in my class GA was causing the compiling error:
This seems to work for me (currently on apple's gcc 4.01): struct GA { Graph *rowGraph; boost::property_map<Graph, int Node::*>::type nmt; GA():rowGraph(0){ rowGraph = new Graph(); nmt = get(&Node::count, *rowGraph); }; ~GA(){ if(rowGraph) delete rowGraph; } }; HTH, Stephan
Stephan Diederich <stephan.diederich <at> googlemail.com> writes:
Hi Shufei,
On 4/10/07, Shufei Fan <fansf <at> hotmail.com> wrote: [snip]
I found out later that a member defined in my class GA was causing the compiling error:
This seems to work for me (currently on apple's gcc 4.01):
struct GA { Graph *rowGraph; boost::property_map<Graph, int Node::*>::type nmt;
GA():rowGraph(0){ rowGraph = new Graph(); nmt = get(&Node::count, *rowGraph); };
~GA(){ if(rowGraph) delete rowGraph; } };
HTH, Stephan
Are you saying initialize the property-pointer in the class GA's constructor? I tried this, I am on windows vc2003.net, but that still doesnot compile. I've switched to using local variable instead(although more local definitions, but easier to get it work anyway) thanks Stephan! Shufei
On 4/15/07, Shufei Fan <fansf@hotmail.com> wrote:
Stephan Diederich <stephan.diederich <at> googlemail.com> writes:
Hi Shufei,
On 4/10/07, Shufei Fan <fansf <at> hotmail.com> wrote: [snip]
I found out later that a member defined in my class GA was causing the compiling error:
This seems to work for me (currently on apple's gcc 4.01):
struct GA { Graph *rowGraph; boost::property_map<Graph, int Node::*>::type nmt;
GA():rowGraph(0){ rowGraph = new Graph(); nmt = get(&Node::count, *rowGraph); };
~GA(){ if(rowGraph) delete rowGraph; } };
HTH, Stephan
Are you saying initialize the property-pointer in the class GA's constructor?
I just wanted to get a working example ;)
I tried this, I am on windows vc2003.net, but that still doesnot compile. I've switched to using local variable instead(although more local definitions, but easier to get it work anyway)
Maybe we can get Doug (the one who made the Bundled Properties) to comment on this... Cheers, Stephan
Stephan Diederich <stephan.diederich <at> googlemail.com> writes:
Are you saying initialize the property-pointer in the class GA's constructor?
I just wanted to get a working example ;)
I tried this, I am on windows vc2003.net, but that still doesnot compile. I've switched to using local variable instead(although more local definitions, but easier to get it work anyway)
Maybe we can get Doug (the one who made the Bundled Properties) to comment on this...
Cheers, Stephan
Simplified sample as follows, produced the error. #include <boost/config.hpp> #include <iostream> // for std::cout #include <fstream> // for std::cout #include <utility> // for std::pair #include <algorithm> // for std::for_each #include <boost/utility.hpp> // for boost::tie #include <boost/graph/graph_traits.hpp> // for boost::graph_traits #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> using namespace boost; struct Node { int count;//pixel number for this region double mode[3];//region mode (RGB) }; struct Edge { double eWeight;//normalized number of common boundary points }; //For accessing mode[3]: //pointer to Node-Mode //new specialization of property_map for bundles with arrays namespace boost{ template <typename Graph, typename T, typename Bundle, unsigned int Size> struct property_map<Graph, T (Bundle::*) [Size]> { private: typedef graph_traits<Graph> traits; typedef typename Graph::vertex_bundled vertex_bundled; typedef typename Graph::edge_bundled edge_bundled; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), typename traits::vertex_descriptor, typename traits::edge_descriptor>::type descriptor; typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value), vertex_bundled, edge_bundled>::type actual_bundle; public: typedef bundle_property_map<Graph, descriptor, actual_bundle, T [Size]> type; typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T [Size]> const_type; }; }; typedef boost::adjacency_list< boost::listS, boost::listS, boost::bidirectionalS, boost::property<vertex_index_t, int, Node>, Edge> Graph; class GA { //data members //Number of points int nRowPnt; int nColPnt; //Graph variables Graph *rowGraph; Graph *colGraph; boost::property_map<Graph, vertex_index_t>::type L_vertex_id, R_vertex_id; boost::property_map<Graph, int Node::*>::type nmt; //methods members public: //default constructor GA(): nRowPnt (0), nColPnt (0), rowGraph(NULL), colGraph(NULL) { rowGraph = new Graph(); colGraph = new Graph(); nmt = get(&Node::count, *rowGraph); } ~GA() { delete rowGraph; delete colGraph; } }; int main() { GA ga; return 0; } /////////////////////////////////////////////////////////////////////////////// error: xxxx...error C2512: 'boost::bundle_property_map<Graph,Descriptor,Bundle,T>' : no appropriate default constructor available with [ Graph=Graph, Descriptor=boost::property_map<Graph,int Node::* >::descriptor, Bundle=Node, T=int ] xxxxxxxxxxx............................ try1 - 1 error(s), 0 warning(s) Thanks, Shufei
participants (2)
-
Shufei Fan
-
Stephan Diederich