Boost logo

Boost :

Subject: Re: [boost] Boost.Variant is not EqualityComparable
From: Stefan Strasser (strasser_at_[hidden])
Date: 2009-11-10 15:48:16


Am Tuesday 10 November 2009 16:13:11 schrieb Cosimo Calabrese:
> 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?

I think even operator== is problematic.
consider this:

struct B{
  bool operator==(B const &) const{ return true; }
};
struct A{
  bool operator==(A const &) const{ return true; }
  bool operator==(B const &) const{ return true; }
};

int main(){
  A a;
  B b;
  boost::variant<A,B> b_var=B(),a_var=A();
  assert(a == b);
  assert( ! (a_var == b_var));
}

this might seem like an outlandish example, but there are real world cases
like that. e.g. pointers of different, but comparable types in a variant.

boost::any doesn't have an operator==.

> >
> > 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


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