I need to cast an any
variable to an original type.
I need to do this:
int i = 10;
any a(i);
int& i2 = any_cast<int &>(a);
But I want that the type stores in any
variable. And I write this:
int i = 10;
any a(i);
a::type_value& i2 = any_cast<a::type_value &>(a); // there is no actually type_value
How can I do something like that? Or how can I extract the original type from the any
variable? Boost.variant is convenient either.
If I cannot do that, then I have another question what C++ techniques and libraries can store and get the type through a function to solve this issue?
The key difference between boost::any and boost::variant is that any can store any type, while variant can store only one of a set of enumerated types. The any type stores a void* pointer to the object, as well as a typeinfo object to remember the underlying type and enforce some degree of type safety.
The boost::any class (based on the class of the same name described in "Valued Conversions" by Kevlin Henney, C++ Report 12(7), July/August 2000) is a variant value type based on the second category. It supports copying of any value type and safe checked extraction of that value strictly against its type.
Boost C++ Libraries Class template optional is a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) contain a valid value. Optional objects offer full value semantics; they are good for passing by value and usage inside STL containers.
Boost. Variant, part of collection of the Boost C++ Libraries. It is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner.
C++ is a statically typed language. The type of a boost::any
is a runtime value; any particular any
could have any type. That's kinda the point.
There is no any::type_value
, because that would have to be a compile time value. And any
is a runtime construct.
Consider this:
void TakeAnAny(boost::any a)
{
a::type_value& i2 = any_cast<a::type_value &>(a);
}
What type is any::type_value
? It is legal to call TakeAnAny
with virtually any type. There is no single compile-time type that any::type_value
could reduce to. And therefore, there is no way for the compiler to determine a type. Since C++ is statically typed, you're hosed.
The ultimate purpose of any is type-erasure. I have some value. And I want to pass that to some other function. This process will go through several different communication layers. But I don't necessarily want all of those different layers to know exactly what type I'm using. I only need myself and my intended destination to know the type. So you stick it in an any
and you're fine. Everyone else just sees the any
, and both of you know what it wraps.
This process only works because both the source and the destination know the real type of the value. If you don't know the type, then you shouldn't be using any
. The purpose of any
is not have a function sit there and cast it to a bunch of possible types (that's what boost::variant
is for). The purpose is to erase the type from a function's signature.
This allows for things like generic messages and signals. You register some event handler with a system. You fire an event that takes an any
as a parameter. The person firing the event knows that the "MouseClick" event always takes a vec2
as its parameter. So every "MouseClick" handler casts it to a vec2
. The "KeyPress" event would maybe pass a int32_t
. So those handlers cast it to that type. And so forth. Everyone knows what type it actually takes.
This used to be done with void*
. The problem there is that you have ownership issues (any
is a value, while void*
is a pointer). Also, a void*
is so type-erased that there's no way to check to see if your cast is correct. any
is really just a type&value-safe void*
; it prevents you from casting to the wrong type.
You don't really want any
. Your use case doesn't seem to want variant
either. What you seem to want is a template. That's a different kind of thing, and it would let you do what you really want: have a function that can use any particular type, while still being able to know exactly what that type is.
Of course, templates have their own limitations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With