Boost logo

Boost :

Subject: Re: [boost] Boost.Variant is not EqualityComparable
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 2009-11-10 10:13:11


Hi to all,

I've the same problem. 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:

http://www.sgi.com/tech/stl/EqualityComparable.html

But as we know, boost::variant doesn't support the inequality
expression. I've tried to add it from my code (I would avoid to modify
the boost lib), but it doesn't works. I've added the attached operator
after the union graph adaptor, but the compiler doesn't resolve the
function.

I'm using MSVS 2005. I don't know if it's my fault or of the compiler
lookup.

If I apply the Brook's patch, it works, but I would to avoid it.

Is this the right way to do?

Thanks,
Cosimo Calabrese.

Eric Friedman wrote:
> I think operator!= (and operator<=, operator>, operator>=) were left out for
> simplicity, but no good reason other than that.
>
> The main issue I considered at the time was that I felt variant should
> forward to the underlying operator. That is, it should call operator!=,
> rather than assume operator!= is equivalent to the negation of operator==.
>
> Maybe there's no need to be this pedantic though. Do others have an opinion?
>
> Eric
>
> On Mon, May 25, 2009 at 6:56 PM, Brook Milligan <brook_at_[hidden]>wrote:
>
>> I just ran into the case that Boost Variant does not satisfy the
>> EqualityComparable concept. While it provides operator==() and
>> operator<() (and therefore is LessThanComparable), it does not provide
>> operator!=(), which is required for the EqualityComparable concept.
>>
>> Is this by design or oversight? It seems reasonable to expect that a
>> Boost Variant model this concept, but perhaps I am missing something.
>>
>> In case it is by oversight, the following patch seems to provide the
>> missing operator.
>>
>> Cheers,
>> Brook
>>
>> --- boost/variant/variant.hpp.orig 2009-05-13 21:21:59.000000000 -0600
>> +++ boost/variant/variant.hpp 2009-05-25 19:21:40.000000000 -0600
>> @@ -1681,6 +1681,8 @@
>> return rhs.apply_visitor(visitor);
>> }
>>
>> + bool operator!=(const variant& rhs) const { return !(*this == rhs); }
>> +
>> bool operator<(const variant& rhs) const
>> {
>> //
>> _______________________________________________
>> Unsubscribe & other changes:
>> http://lists.boost.org/mailman/listinfo.cgi/boost
>>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


/*
  the type:
 
  graph_traits<union_graph<Graph1, Graph2> >::edge_descriptor
 
  is defined as:
 
  typedef boost::variant< WR1<typename graph_traits<Graph1>::edge_descriptor>,
                          WR2<typename graph_traits<Graph2>::edge_descriptor> > edge_descriptor;
 */

    namespace detail {
      template <typename Graph1, typename Graph2>
      inline bool operator!=( const typename graph_traits<union_graph<Graph1, Graph2> >::edge_descriptor& left,
                              const typename graph_traits<union_graph<Graph1, Graph2> >::edge_descriptor& right )
      {
        return !( left == right );
      }
    }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk