boost::any
is a decently efficient way to store a value of a type you have prevented the compiler (for whatever reason or design requirement) from knowing.
If there are only a limited set of operations you want to perform on the data, you can use type erasure instead and/or a base interface class. But that requires knowing all uses for the data when you define the interface.
If you have a limited set of data types, boost::variant
or the like can be more efficient than any
. You can even have a variant
that includes any
or a type erasure object (or objects) in the set of types.
You can use reflection or similar techniques to store complex data and wrap it in any
accessors (or variant
) if your data is sometimes structured, which can reduce storage overhead somewhat. Basically structured data becomes a type erased type with member access by name.
Much of these techniques end up mirroring type behaviour of scripting or bytecode languages: sometimes it might be a good idea to write the part of your app that needs this amount of compile time flexibilty in a mainly runtime type checked language.
Finally you may decide you do not need all this needless runtime dynamic typing.