Hi.
I encountered the need to query a boost::variant to which type it
currently contain. I'm talking about something like:
variant
On Sat, 29 Jan 2005 17:56:59 +0200, Yuval Ronen
Hi. I encountered the need to query a boost::variant to which type it currently contain. I'm talking about something like:
variant
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
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
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
(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
Hi. I encountered the need to query a boost::variant to which type it currently contain. I'm talking about something like:
variant
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
bool variant_is_a(const Variant& v) { BOOST_MPL_ASSERT(( boost::mpl::contains )); 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.
Your code works beautifully. I really hope this feature will find its way to the variant library.
Hi, I can imagine cases where the current behavior might be preferable (e.g., uses of variant types in generic contexts). But I think for the vast majority of cases, and especially in non-generic contexts, checking the type as you propose is a good idea. I will determine a way to work this into the library, either by modifying the semantics of boost::get or by introducing a new accessor function. Thanks for the input. Eric Friedman Co-author of Variant library Yuval Ronen wrote:
Hi. I encountered the need to query a boost::variant to which type it currently contain. I'm talking about something like:
variant
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
bool variant_is_a(const Variant& v) { BOOST_MPL_ASSERT(( boost::mpl::contains 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.
Your code works beautifully. I really hope this feature will find its way to the variant library.
Eric Friedman wrote:
Hi,
I can imagine cases where the current behavior might be preferable (e.g., uses of variant types in generic contexts). But I think for the vast majority of cases, and especially in non-generic contexts, checking the type as you propose is a good idea.
I will determine a way to work this into the library, either by modifying the semantics of boost::get or by introducing a new accessor function. Thanks for the input.
Eric Friedman Co-author of Variant library
Great! Thanks a lot. BTW, another two small remarks: The "variant::types" typedef that was used here is not documented, and it will be helpful if I could read about it and about its possible usages. And if you wish not to burden the users with mpl, then it's possible to wrap mpl::contains in a constant boolean value "can_be", as I suggested. But anyway, thanks again.
On Thu, 03 Feb 2005 00:33:37 +0200, Yuval Ronen
Eric Friedman wrote:
Hi, I can imagine cases where the current behavior might be preferable (e.g., uses of variant types in generic contexts). But I think for the vast majority of cases, and especially in non-generic contexts, checking the type as you propose is a good idea. I will determine a way to work this into the library, either by modifying the semantics of boost::get or by introducing a new accessor function. Thanks for the input. Eric Friedman Co-author of Variant library
Great! Thanks a lot.
BTW, another two small remarks: The "variant::types" typedef that was used here is not documented, and it will be helpful if I could read about it and about its possible usages. And if you wish not to burden the users with mpl, then it's possible to wrap mpl::contains in a constant boolean value "can_be", as I suggested.
variant::types is documented here: http://boost.org/doc/html/boost/variant.html Bruno
While you're at it, any possibility you could add serialization to boost::variant? Robert Ramey Bruno Martínez Aguerre wrote:
On Thu, 03 Feb 2005 00:33:37 +0200, Yuval Ronen
wrote: Eric Friedman wrote:
Hi, I can imagine cases where the current behavior might be preferable (e.g., uses of variant types in generic contexts). But I think for the vast majority of cases, and especially in non-generic contexts, checking the type as you propose is a good idea. I will determine a way to work this into the library, either by modifying the semantics of boost::get or by introducing a new accessor function. Thanks for the input. Eric Friedman Co-author of Variant library
BTW, another two small remarks: The "variant::types" typedef that was used here is not documented, and it will be helpful if I could read about it and about its possible usages.
variant::types is documented here: http://boost.org/doc/html/boost/variant.html
Bruno
Well, first of all, you're right. My mistake, I missed it. However, when thinking about why I missed it, I realized that its because it's not a colored link, like all other classes/functions. Why should a typedef be underprivileged compared to classes/functions? It's part of the interface and should be documented in the same way (and not just as a side note). I hope I'm not too much of a nagger... :-)
participants (4)
-
Bruno Martínez Aguerre
-
Eric Friedman
-
Robert Ramey
-
Yuval Ronen