Is there any non-awful way to have a collection of objects of more than one type? I'm perfectly happy to derive each type from a common base. I need sensible semantics so the collection can be copied, assigned, and so on.
Obviously, I can't just use a vector or list of the base class. Objects will be sliced and copying won't work at all. Using vectors or lists of pointers or smart pointers works, but you don't get sane copy semantics.
To get sane copy semantics, you need to use something like Boost's ptr_vector
. But this requires a painful and error-prone infrastructure. Essentially, you can't just derive a new class from the base class because if it ever goes into the collection, it will not be properly copied.
This seems like such a common thing to do and all the solutions I know of are so awful. It seems like C++ is fundamentally missing a way to create a new instance of an object identical to a given instance -- even if that type has a copy constructor. And making a clone
or duplicate
function requires careful overloading in every derived class. If you fail to do it when creating a new class derived from the base (or any other class derived from that base) -- boom, your collection breaks.
Is there really no better way?
You can use
std::vector<boost::any>
to do most of this I think.For which I get the output:
Which is what I expect to see.
EDIT:
In line with your requirements to be able to treat members as some common base-type you'll need something very similar to
boost::any
, which thankfully is a relatively simple class.Now you should be able to do this:
I actually dislike the syntax of any_cast and would use this opportunity to add an "as" member function.. so that I could write the last line as: