Boost logo

Boost Users :

From: Bruno Martínez Aguerre (br1_at_[hidden])
Date: 2005-01-31 08:19:51


On Sat, 29 Jan 2005 17:56:59 +0200, Yuval Ronen <ronen_yuval_at_[hidden]>
wrote:

> Hi.
> I encountered the need to query a boost::variant to which type it
> currently contain. I'm talking about something like:
>
> variant<int, string> v(3);
> assert(v.is_a<int>());
> assert(!v.is_a<string>());

Take a look at get(), it's almost what you need. Unfortunately, it
compiles even when the type cannot be inside the variant. This can be
fixed with mpl::contains:

template<typename T, typename Variant>
bool variant_is_a(const Variant& v)
{
      BOOST_MPL_ASSERT(( boost::mpl::contains<typename Variant::types,T> ));
      return boost::get<T>(&v) != 0;
}

There should be a version of get that works as variant_is_a above. IMHO,
the current behaviour is more dangerous than that of variant_is_a, so
get() should be changed and maybe a new function be created that keeps the
current behaviour. Some code may break with this change with a compile
error that would go away if the other version of get is used.

Bruno

>
> This can be done using the which() method, but its drawback is that I
> rely on the order of the types in the variant declaration rather on the
> type, which is really what I'm interested in.
>
> I can implement the variant_is_a<>() feature using a visitor such as:
>
> template <typename T>
> struct is_a_visitor : public boost::static_visitor<bool>
> {
> template <typename U>
> bool operator()(const U &) const { return false; }
>
> bool operator()(const T &) const { return true; }
> };
>
> template <typename T, class Variant>
> bool variant_is_a(const Variant &v)
> {
> return v.apply_visitor(is_a_visitor<T>());
> }
>
> but this way has a problem: calling variant_is_a<double>() on a variant
> of type variant<int, string> (no double for this variant) will simply
> return false, rather than just not compile, which is what I prefer.
> Making this not compile will require a new feature from variant: a
> boolean constant 'can_be'. With this, the variant_is_a() function could
> be written with additional line:
>
> BOOST_STATIC_ASSERT(Variant::can_be<T>::value);
>
> IMO, the is_a/can_be features are general and useful enough to be
> included in the library. Wouldn't you agree?

> Yuval


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net