Boost logo

Boost :

Subject: [boost] [Variant] [BGL] Variant<edge_descriptor, edge_descriptor> is not EqualityComparable
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 2009-11-12 06:05:33

Hi to all,

this discussion is linked to "Boost.Variant is not EqualityComparable".
I've opened a new one because to involve the BGL argument.

The problem is simply this. I've created a union graph adaptor, that
provides a "union view" of two graphs; in that adaptor, the
edge_descriptor is defined like this:

typedef boost::variant<
       WR1<typename graph_traits<Graph1>::edge_descriptor>,
       WR2<typename graph_traits<Graph2>::edge_descriptor>
> edge_descriptor;

Now I would to use that graph to the Dijkstra's algorithm, that requires
that the edge_descriptor models the EqualityComparable concept. But as
we know, boost::variant doesn't support the inequality expression ( v1
!= v2 ). I've tried to add it from my code (I would avoid to modify the
boost lib), but it doesn't works.

I'm using MSVS 2005 on WinXP, boost 1.38.

I've tried to add the following line, as suggested by Stefan Strasser
(thanks Stefan):

using namespace std::rel_ops;

to add the generic operator!=(), but the compiler doesn't find it, the
compiler error is the same.

Now I try to provide to you more details. If it isn't enough, I can
provide the entire code.

I've defined the graph adaptor like this:

////// union_graph.hpp //////
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/exception.hpp>
#include <boost/variant.hpp>

namespace boost {

   template <typename T>
   class WR1 { /* ... */ };

   template <typename T>
   class WR2 { /* ... */ };

   template <typename Graph1, typename Graph2>
   class union_graph {
     typedef Graph1 graph_type1;
     typedef Graph2 graph_type2;

     // Constructor
     union_graph( Graph1& g1, Graph2& g2 ) : m_g1(g1), m_g2(g2)
     { /* ... */ }

     // Graph requirements
     typedef boost::variant<
       WR1<typename graph_traits<Graph1>::vertex_descriptor>,
       WR2<typename graph_traits<Graph2>::vertex_descriptor>
> vertex_descriptor;

     /* ... */

     // IncidenceGraph requirements
     typedef boost::variant<
       WR1<typename graph_traits<Graph1>::edge_descriptor>,
       WR2<typename boost::graph_traits<Graph2>::edge_descriptor>
> edge_descriptor;

     /* ... */


// EqualityComparable concept, requested by IncidenceGraph concept
template <typename Graph1, typename Graph2>
inline bool operator!=(
   const typename boost::graph_traits<
                            boost::union_graph<Graph1, Graph2>
>::edge_descriptor& left,
   const typename boost::graph_traits<
                            boost::union_graph<Graph1, Graph2>
>::edge_descriptor& right )
     return !( left == right );

and I've used it like this:

////// main.cpp //////
#include "union_graph.hpp"

int main()
   typedef adjacency_list<...> Graph1;
   typedef adjacency_list<...> Graph2;
   typedef union_graph<Graph1, Graph2> UG;

   Graph1 g1( 10 );
   Graph1 g2( 10 );
   UG ug( g1, g2 );

   graph_traits<UG>::edge_descriptor e1;
   graph_traits<UG>::edge_descriptor e2;

   tie( e1, existence ) = edge( v1, v2, g );
   tie( e2, existence ) = edge( v1, v2, g );

   e1 != e2;

The first part of the template compiler error is:

: error C2678: binary '!=' : no operator found which takes a left-hand
operand of type 'boost::variant<T0_,T1>' (or there is no acceptable
1> with
1> [
unsigned int>>,
unsigned int>>
1> ]

Can someone help me? I wouldn't hack the lib, because I will do it to
every new version of Boost...

Thanks in advance,
Cosimo Calabrese.

Boost list run by bdawes at, gregod at, cpdaniel at, john at