views:

144

answers:

3

Hi,

I found a very useful answer on how to create templated graphs using boost::graph under http://stackoverflow.com/questions/671714/modifying-vertex-properties-in-a-boostgraph/950173#950173

For me, this is very convenient as long as I do all the work on the graph in the Graph-class itself.

However, it might be necessary to access information from outside, e.g. one might want to implement a Printer-class that takes a Graph-object and prints out all the stored information.

In that case, it could be handy to access all the vertices (e.g. by a vertex iterator). Unfortunately, this won't work, as all the typedef is done in the Graph-class and this information is not accessible from outside, so the Printer-class won't know what a vertex-iterator etc. is.

How could I address this issue and still keep the templated aspect?

Thanks.

A: 

But the typedefs are public, so you can access them from outside:

template<typename T>
class A
{
public:
    typedef T type;
    typedef unsigned data;
};

Now this is the following:

A<int>::type // int
A<int>::data // unsigned

Be careful, if T is not specified

template<typename T>
void func( A<T>& a )
{
    typename A<T>::type // T
    typename A<T>::data // unsigned
}
Rupert Jones
Thank you. I don't know why I haven't thought about that myself. It's constantly used when using a library and accessing some elements there, but I couldn't quite make the connection on my own... *doooh*Thanks also to the other answerers.Is this the same as using a namespace, or is this slightly different?
Shadow
What do you mean by using a namespace? I cannot see the connection. In a namespace it would be typename ns::A<T>::type, if ns is the name of the namespace. Do you mean that?
Rupert Jones
A: 

Unfortunately, this won't work, as all the typedef is done in the Graph-class and this information is not accessible from outside

I don’t quite follow … the typedefs are all public so they are very well accessible from the outside. Just take care to use typename when accessing a dependent name:

typename Graph<TProp, TEdge>::vertex_iterator i;
Konrad Rudolph
A: 

Your question is a bit confusing to me, but I guess you are looking for something like this:

// console was chosen just to make the example simple, but 
// it can be more generic easily
template <typename vertex_t>
class ConsolePrinter {
public:
    template <typename iter_t>
    void print(iter_t vbegin, iter_t vend) const {
       copy(vbegin, vend, std::ostream_iterator<vertex_t>(std::cout, "\r\n"));
    }
};

Then, following the example you linked, you would have something like this:

typedef Graph<VertexProperties, EdgeProperties> MyGraph;
MyGraph g;
MyGraph::vertex_range_t vertices_range = g.getVertices(); 
ConsolePrinter<MyGraph::Vertex> printer;   
printer.print(vertices_range.first,vertices_range.second);

As Konrad and others already have said in this thread, you have no problem acessing the iterator and other typedefs from that class and you can keep your solution very generic. By the way, the printing solution you choose will impose some expectations (in my case, the vertex type has to be able to work with operator<< of a ostream), but this can be dealed without a loss of the generic aspect of the solution.

fogo