How to store variant data in C++
As of C++17, there’s std::variant
.
If you can’t use that yet, you might want Boost.Variant. A similar, but distinct, type for modelling polymorphism is provided by std::any
(and, pre-C++17, Boost.Any).
Just as an additional pointer, you can look for “type erasure”.
While Konrad's answer (using an existing standardized solution) is certainly preferable to writing your own bug-prone version, the boost variant has some overheads, especially in copy construction and memory.
A common customized approach is the following modified Factory Pattern:
- Create a Base interface for a generic object that also encapsulates the object type (either as an enum), or using 'typeid' (preferable).
- Now implement the interface using a template
Derived
class. - Create a factory class with a templateized
create
function with signature:
template <typename _T> Base * Factory::create ();
This internally creates a Derived<_T>
object on the heap, and retuns a dynamic cast pointer. Specialize this for each class you want implemented.
Finally, define a Variant
wrapper that contains this Base *
pointer and defines template get and set functions. Utility functions like getType()
, isEmpty()
, assignment and equality operators, etc can be appropriately implemented here.
Depending on the utility functions and the factory implementation, supported classes will need to support some basic functions like assignment or copy construction.