Boost logo

Boost Users :

Subject: Re: [Boost-users] randomize_property question
From: mcorbion_at_[hidden]
Date: 2009-08-14 18:40:04


On Fri, 14 Aug 2009, mcorbion_at_[hidden] wrote:

> Ok so I still can't use the randomize property but I've done a workaround.
> I created an AbstractGraph class which has a m_Graph adjacency_list type
> of graph. And nodes uses the bundled property :
> struct City
> {
> int pos_X;
> int pos_Y;
> };
>
>
> My workaround test function uses the property map given to randomly set
> the values, but it's still too specific :
>
> template <typename Graph, typename BundProp,typename RandomGenerator>
> void AbstractGraph::test(bundle_property_map<Graph,unsigned
> int,BundProp,int> p_PMap, RandomGenerator& p_ewrg){
>
> AbstractGraph::N_iterator l_NodeStart;
> AbstractGraph::N_iterator l_NodeEnd;
> AbstractGraph::GetNodes(l_NodeStart,l_NodeEnd);
>
> for (; l_NodeStart != l_NodeEnd; ++l_NodeStart) {
> p_PMap[*l_NodeStart] = p_ewrg();
> }
> }
>
> called this way in the main :
>
> mt19937 l_Gen(1988);
> boost::uniform_int<> RandRange(1,10);
> boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
> ew2rg(l_Gen, RandRange);
>
>
> typedef property_map<Graph, int(City::*)>::type t_PMapCity;
> t_PMapCity l_PMap=get(&City::pos_X,m_Graph);
> test<Graph,City>(l_PMap,ew2rg);
>
>
> I would like to include the two line that generates the property_map from
> the main to the test function. I've tried this :
>
> template <typename Graph, typename PropertyTagType,typename
RandomGenerator>
> void AbstractGraph::test2( ??? p_PropertyTagName,RandomGenerator& p_ewrg){
>
> typedef property_map<Graph, PropertyTagType>::type t_PMap;
> t_PMap l_PMap=get(PropertyTagName,m_Graph);
> AbstractGraph::N_iterator l_NodeStart;
> AbstractGraph::N_iterator l_NodeEnd;
> AbstractGraph::GetNodes(l_NodeStart,l_NodeEnd);
>
> for (; l_NodeStart != l_NodeEnd; ++l_NodeStart) {
> p_PMap[*l_NodeStart] = p_ewrg();
> }
> }
>
> called this way :
>
> test2<Graph,int(City::*)>(l_Gen, &City::pos_X);
>
> But I can't figure any type for &City::pos_X in order to write the header
> for test2 allowing the function to work with float, char ...

The type of &City::pos_X should be "int City::*" (without the extra
parentheses); however, argument deduction should pick that up for you
automatically, both for this code and randomize_property. The ??? in
test2 should be PropertyTagType, I believe.

-- Jeremiah Willcock

Thanks a lot for the help. I've changed test2 and it works! Here's the
code for those who encounters the same problem :

template <typename Graph, typename PropertyTagType,typename RandomGenerator>
void AbstractGraph::test2( PropertyTagType
p_PropertyTagName,RandomGenerator& p_ewrg){

    typedef property_map<Graph, PropertyTagType>::type t_PMap;
    t_PMap l_PMap=get(p_PropertyTagName,m_Graph);
    AbstractGraph::N_iterator l_NodeStart;
    AbstractGraph::N_iterator l_NodeEnd;
    AbstractGraph::GetNodes(l_NodeStart,l_NodeEnd);

    for (; l_NodeStart != l_NodeEnd; ++l_NodeStart) {
        l_PMap[*l_NodeStart] = p_ewrg();
    }
}
and how to call it :

    test2<Graph>(&City::pos_X,ew2rg);
    //or test2<Graph,int City::*>(l_Gen,&City::pos_X);

As you said deduction picked up for me the typename for PropertyTagType
but putting directly the type "int City::*" doesn't work for the template
in randomize_property (whereas it works with my function test 2).

randomize_property<int City::*>(m_Graph,ew2rg);

It gives me this compiling error :

\boost\pending\property.hpp(47) : error C2825: 'PropertyTag' : doit être
une classe ou un espace de noms lorsqu'il est suivi par '::'
\boost\graph\random.hpp(196) : voir la référence à l'instanciation de la
classe modèle 'boost::property_kind<PropertyTag>' en cours de compilation

which translates to :
\boost\pending\property.hpp(47) : error C2825: PropertyTag must be a class
or a namespace when followed by '::'
\boost\graph\random.hpp(196) : see the reference at instanciation of the
model class 'boost::property_kind<PropertyTag>'

In randomize_property there are no input of the Class Property :
  template<class Property, class G, class RandomGenerator>
  void randomize_property(G& g, RandomGenerator& rg)
It only tries to get the property_kind from it :
typename property_kind<Property>::type()
In order to invoke the more detailed function.

And even when I will have the errorC2825 fixed, I think that my City
structure having no "kind" element, it won't be able to pick the right
detailed function. I checked property_kind and it redefines "kind" into
"type" :
  template <class PropertyTag>
  struct property_kind {
    typedef typename PropertyTag::kind type;
  };

To sum it up I now have three questions ^^:
1
How can I solve the errorC2825? because the template instanciation works
fine with my test2 function and not with the randomize_property

2
Will the property_kind structure work with a bundled property? And if not
here's the question 3...

3
Is there a way to get to know from a bundled property if it's an
edge_property_tag or a vertex_property_tag? This way I could directly use
detail::randomize_property and give it myself.

P.S for number 3 :
I thought about adding "kind" in my Struct City from the type :
boost::vertex_property_tag. So I could use it in my detailed
randomize_property call, but if there is another way I would be happy to
know it.

Thanks in advance
M.Corbion


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net