You could also create an interface, which your foo struct will implement, have the vector hold pointers to this interface. As it stands, foo<color>, foo<record> are completely different unique types and cannot be mixed within the same vector.
It just depends on what you want/need/can get away with and what pros/cons you are willing to accept. With this latter approach there will need to be some casting...
This is just for an idea, it is very simple, maybe too simple..
That's a downside to unions: a data member cannot have a default constructor, copy-constructor, move-constructor, copy-assignment operator, move-assignment operator, or destructor. For built-in types, though, it's quite nifty.
> That's a downside to unions: a data member cannot have a default constructor ...
Not really. Just that if any non-static data member of a union has a non-trivial copy constructor, the copy constructor of the union is implicitly deleted unless a user-defined copy constructor is provided. And likewise for the other foundation operations.