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

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@biology.nmsu.edu>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

On Wed, May 27, 2009 at 11:50 AM, Eric Friedman <ebf@users.sourceforge.net> 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@biology.nmsu.edu>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 { //
I use Boost.Variant quite often, and I never even thought it had operators, I just did everything using custom-made visitors, but if it did expose all those operators and delegate them down to the internal types if they are the same type, I would love that actually, would actually save me quite a bit of code in some places. Although, thinking of it, perhaps I would want something like variantA==variantB to test that the types are equal and that is it, and perhaps something like (*variantA)==(*variantB) to test both types and delegate to the internal objects, that form I would consider perfect.

On Wed, May 27, 2009 at 1:50 PM, Eric Friedman <ebf@users.sourceforge.net> 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?
Could this be useful in the case of something like boost::tribool as a variant type? For example: tribool a(true); tribool b(indeterminate); if ((a==b) || (a!=b)) assert(false); It would be nice if boost::variant<> with a tribool bounded type could maintain this behavior, which it seems like it would as long as operator!=() is separately forwarded. -- Matthew L. Creech

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@biology.nmsu.edu>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 ); } }

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.
if that's the case then I think the error is to be found in the graph library. EqualityComparable does not require operator !=, the SGI link above is probably outdated. the standard (at least a draft from around 2005, I haven't bought the official document) doesn't state that requirement. using namespace std::rel_ops; should fix these problems though.

Thanks Stefan, I've opened a new discussion because to involve the BGL argument. The discussion is: [Variant] [BGL] Variant<edge_descriptor, edge_descriptor> is not EqualityComparable I've replied to you in that discussion. Cosimo Calabrese Stefan Strasser wrote:
using namespace std::rel_ops;
should fix these problems though.

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@biology.nmsu.edu>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
participants (6)
-
brook@biology.nmsu.edu
-
Cosimo Calabrese
-
Eric Friedman
-
Matthew L. Creech
-
OvermindDL1
-
Stefan Strasser