
Jeremiah Willcock ha scritto:
I think that should work. You might really want a tagged union type, though (boost::variant with some guarantee that the edge descriptor types of the two graphs are different is an example). You would need to do wrapping of each graph's descriptors in the union iterator then, though. That would remove the restrictions on edges that you gave above. I don't know what you need as far as properties; those might need to be combined as well.
Hi Jeremiah, I've readed some days ago your suggestions about using boost::variant, but I ignored what boost::variant is. So I've spent some time to study it, and now I think I understand what you have suggested to me. E.g. the edge_descriptor of union_graph adaptor is a boost::variant, that contains the edge_descriptor of both the graph. When I call the source() function I pass an edge_descriptor to it, but the source() doesn't know if the edge_descriptor belongs to one or another graph. So the source() function use a source_visitor, that distinguish between the edge_descriptors, and call the source() on the right graph. Can you take a look to the attached code? Is this that you meant? I've writed only the case of the source() function, but at every concept function corresponds a visitor. Thanks for your help, Cosimo Calabrese. class union_graph; //=========================================================================== // source_visitor template<typename Graph1, typename Graph2> class source_visitor : public boost::static_visitor<> { public: source_visitor( const union_graph<Graph1, Graph2>& g ) : m_g( g ) {} union_graph<Graph1, Graph2>::vertex_descriptor operator()( const typename graph_traits<Graph1>::edge_descriptor& e ) const { return source( e, m_g.m_g1 ); } union_graph<Graph1, Graph2>::vertex_descriptor operator()( const typename graph_traits<Graph2>::edge_descriptor& e ) const { return source( e, m_g.m_g2 ); } private: const union_graph<Graph1, Graph2>& m_g; }; //=========================================================================== // union_graph template<typename Graph1, typename Graph2> class union_graph { public: union_graph( const Graph1& g1, const Graph2& g2 ) : m_g1( g1 ), m_g2( g2 ) {} typedef graph_traits<Graph1> Traits1; typedef graph_traits<Graph2> Traits2; typedef typename boost::variant( Traits1::vertex_descriptor, Traits2::vertex_descriptor ) vertex_descriptor; typedef typename boost::variant( Traits1::edge_descriptor, Traits2::edge_descriptor ) edge_descriptor; // ... friend class source_visitor; private: const Graph1& m_g1; const Graph2& m_g2; }; template<typename Graph1, typename Graph2> typename union_graph<Graph1, Graph2>::vertex_descriptor source( const typename union_graph<Graph1, Graph2>::edge_descriptor& e, const union_graph<Graph1, Graph2>& g ) { return boost::apply_visitor( source_visitor( g ), e ); }