[BGL] Getting/deducing type of custom (internal) properties

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[BGL] Getting/deducing type of custom (internal) properties

Cedric Laczny
Hi,

this is to substitute the thread: [BGL] Accessing internal properties and
returning a "template"-type

I think I can now deliver even more details on my problem.

Again, I have the following concept:

template < class GRAPH, class EDGE_PREDICATE, class VERTEX_PREDICATE >
class FilteredGraph
{
public:
   
    /// Defines an alias type to represent the filtered_graph
    typedef filtered_graph< GRAPH, EDGE_PREDICATE, VERTEX_PREDICATE >
FilteredGraphContainer;


//
// some c'tors, member functions etc.
//
    template< class VERTEXPROPERTIES >
    VERTEXPROPERTIES& properties(const Vertex& v) const
    {
            typename property_map<FilteredGraphContainer,
vertex_properties_t>::const_type param = get(vertex_properties, graph_);
            return (param[v]);
    }

//
// some more stuff
//

private:
        FilteredGraphContainer graph_;
};

The compiler can't obviously deduce the type of the return-value of
properties( Vertex v) as this type is not specified in the argument list.
This is what I understood so far by finding this:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.4

I have the same properties-function in my Graph-class, which uses custom
properties as in
 http://live.boost.org/doc/libs/1_43_0/libs/graph/doc/using_adjacency_list.html#sec:adjacency-
list-properties

The definition of this class basically is:
enum vertex_properties_t { vertex_properties };
enum edge_properties_t { edge_properties };
namespace boost {
        BOOST_INSTALL_PROPERTY(vertex, properties);
        BOOST_INSTALL_PROPERTY(edge, properties);
}

/* the graph base class template */
template < typename VERTEXPROPERTIES, typename EDGEPROPERTIES >
class Graph
{
public:

    /// an adjacency_list like we need it
    typedef adjacency_list<
            setS, // disallow parallel edges
            vecS, // vertex container
            undirectedS, // undirected graph
            property<vertex_properties_t, VERTEXPROPERTIES>,
            property<edge_properties_t, EDGEPROPERTIES>
    > GraphContainer;
//
//...
//
private:
        GraphContainer graph_;
};

This is all, more or less, similar to the template-definitions used in the BGL,
or at least that was my intention.

Interestingly, when I have a function:

template< class GRAPH >
void some_function( const GRAPH& g){
GRAPH::Vertex v;
// Get some included vertex out of g and assign it to v;
v = someVertexFromG( g );
filtered_graph< GRAPH, keep_all, keep_all > fg(g, keep_all(), keep_all());
get(vertex_properties, fg, v);
}

it works without any problem.

Now the question, is it possible to solve this issue for FilteredGraph and
keep the same concept as for Graph, or do I need to specify the type of
VERTEXPROPERTIES somewhere _beforehand_ in order to let the compiler get this
type (not preferred, for obvious reasons)?

Best,

Cedric
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [BGL] Getting/deducing type of custom (internal) properties

Cedric Laczny
Hi,

I was able to figure out ta solution for the problem. I am fairly sure that it
was the fact that the compiler could not deduce the type there because it was
not specified in the arguments.
In fact, the compiler doesn't even need to do this automatically. Because a
filtered_graph always needs an adjacency_list as its input, which, in turn
needs to have appropriate types for the vertex/edge properties.

These types can be retrieved via the property_traits interface.

The solution I now came up with goes like this:

First, one needs to find out the appropriate type:
    /// Type of the internal properties of the vertices
    typedef typename property_traits< typename
property_map<FilteredGraphContainer, vertex_properties_t>::type >::value_type
VProps;

And then, this type can be used.
    VProps& properties(const Vertex& v)
    {  
            typename property_map<FilteredGraphContainer,
vertex_properties_t>::type param = get(vertex_properties, graph_);
            return (param[v]);
    }

Interestingly, this works also for defining FilteredGraphs from FilteredGraph.
If this makes sense or not may be individual opinion, I just wanted to state
that it works.
IMHO, using a template here, would actually be false (maybe that's why it
didn't work), as the type is depending on the type of the original graph.

Another way to circumvent such issues might be to use bundled properties. But
they are not compatible to older versions of the BGL or not compatible with
special compilers.

Best,

Cedric

On Wednesday, 17. November 2010 10:53:51 you wrote:

> Hi,
>
> this is to substitute the thread: [BGL] Accessing internal properties and
> returning a "template"-type
>
> I think I can now deliver even more details on my problem.
>
> Again, I have the following concept:
>
> template < class GRAPH, class EDGE_PREDICATE, class VERTEX_PREDICATE >
> class FilteredGraph
> {
> public:
>
>     /// Defines an alias type to represent the filtered_graph
>     typedef filtered_graph< GRAPH, EDGE_PREDICATE, VERTEX_PREDICATE >
> FilteredGraphContainer;
>
>
> //
> // some c'tors, member functions etc.
> //
>     template< class VERTEXPROPERTIES >
>     VERTEXPROPERTIES& properties(const Vertex& v) const
>     {
>             typename property_map<FilteredGraphContainer,
> vertex_properties_t>::const_type param = get(vertex_properties, graph_);
>             return (param[v]);
>     }
>
> //
> // some more stuff
> //
>
> private:
> FilteredGraphContainer graph_;
> };
>
> The compiler can't obviously deduce the type of the return-value of
> properties( Vertex v) as this type is not specified in the argument list.
> This is what I understood so far by finding this:
> http://www.parashift.com/c++-faq-lite/templates.html#faq-35.4
>
> I have the same properties-function in my Graph-class, which uses custom
> properties as in
>  http://live.boost.org/doc/libs/1_43_0/libs/graph/doc/using_adjacency_list.
> html#sec:adjacency- list-properties
>
> The definition of this class basically is:
> enum vertex_properties_t { vertex_properties };
> enum edge_properties_t { edge_properties };
> namespace boost {
>         BOOST_INSTALL_PROPERTY(vertex, properties);
>         BOOST_INSTALL_PROPERTY(edge, properties);
> }
>
> /* the graph base class template */
> template < typename VERTEXPROPERTIES, typename EDGEPROPERTIES >
> class Graph
> {
> public:
>
>     /// an adjacency_list like we need it
>     typedef adjacency_list<
>             setS, // disallow parallel edges
>             vecS, // vertex container
>             undirectedS, // undirected graph
>             property<vertex_properties_t, VERTEXPROPERTIES>,
>             property<edge_properties_t, EDGEPROPERTIES>
>
>     > GraphContainer;
>
> //
> //...
> //
> private:
> GraphContainer graph_;
> };
>
> This is all, more or less, similar to the template-definitions used in the
> BGL, or at least that was my intention.
>
> Interestingly, when I have a function:
>
> template< class GRAPH >
> void some_function( const GRAPH& g){
> GRAPH::Vertex v;
> // Get some included vertex out of g and assign it to v;
> v = someVertexFromG( g );
> filtered_graph< GRAPH, keep_all, keep_all > fg(g, keep_all(), keep_all());
> get(vertex_properties, fg, v);
> }
>
> it works without any problem.
>
> Now the question, is it possible to solve this issue for FilteredGraph and
> keep the same concept as for Graph, or do I need to specify the type of
> VERTEXPROPERTIES somewhere _beforehand_ in order to let the compiler get
> this type (not preferred, for obvious reasons)?
>
> Best,
>
> Cedric

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users