In addition to HolyBlackCat's excellent answer, I should also mention you do have a couple of other options to achieve a similar effect.
If you have some subset of classes, you can inherit them all from the same base like this:
class Base {
};
class Derived1 : public Base {
};
class Derived2 : public Base {
};
Then, you can create a Box
like this:
Box<std::uinque_ptr<Base>> genericBox;
genericBox
can now hold any derived, though because of the way C++ works, you probably need to hold it by pointer, reference, or std::unique_ptr
. Consequently, this is kind of messy, but works.
Also, I should mention that using this method will not work for types like int
or double
, so this is probably not useful if you need to use those types.
Better is, if you have access to it, to use std::variant
. This will allow you to store a specific set of types:
Box<std::variant<int, double>> genericBox;
This genericBox
can hold either a double
or an int
.
If you don't have direct access to std::variant
, there is also a boost::variant
which is basically the same thing. Or, if you have access to neither, you do have the option of a union
:
union GenericType {
int myInterger;
double myDouble;
};
Box<GenericType> genericBox;
Of course, std::variant
and boost::variant
is better, but this will work for you if you're ever in a situation where you don't have those.
Now, these options will only work if you ever know ahead of time what types you are attempting to store. If you don't know that, you have the option of std::any
:
Box<std::any> genericBox;
As with std::variant
, there is also a boost::any
. You can also implement it yourself if you really have to for some crazy reason. But I wouldn't recommend doing that unless you are doing it for educational purposes or something.