Reputation: 5239
boost::variant defines operator < as follows:
If which() == rhs.which() then: content_this < content_rhs, where content_this is the content of *this and content_rhs is the content of rhs. Otherwise: which() < rhs.which().
This is not what I want, because I'd like to fail some < comparison. For example, if I have a variant like this:
typedef boost::variant<int, double, std::string> DataType;
I want DataType(1) < DataType(2.0) to succeed but DataType(1) < DataType("2") to throw exception. Is there any way to achieve this?
I can't define
bool operator < (const Field& lhs, const Field& rhs)
because it will conflict with member operator < defined in variant class.
I can define a static_visitor, but I'd like to know if there's anyway to overload operator <.
Upvotes: 1
Views: 204
Reputation: 11181
While wrapping yourDataType
inside another struct is surely the best solution, keep in mind that if you need a quick and dirty fix this works:
namespace boost
{
template<>
bool DataType::operator<(const DataType &) const
{
// impl
}
}
In C++11 you should be able to avoid the namespace boost
.
Notice that this will break the ODR unless all your TU see this specialization before actually using it.
Upvotes: 1
Reputation: 275270
Create a struct
containing nothing but a boost::variant<Ts...> v;
. Forward your constructors to it (possibly some manually). Provide an operator boost::variant<Ts...>()
optionally.
Have your own <
on this struct
.
Note, however, that boost::variant
is intended to normalize the union. It is supposed to be normal that some variant
s are one type, and some are another type.
<
is usually in std::map
type containers or when sorting. Having the keys be forced to be all the same type, or the sorted elements to be all the same type, seems like a bad idea. The variant
shouldn't contain both types if it isn't expected for any such variant
to contain both types.
The places where <
is automatically used all tend to expect an optional ordering predicate object. I personally cannot think of why I'd ever use an exception throwing predicate object manually, which makes me leery of making yours the default.
Upvotes: 1