I am wondering if I'm doing it right, with regard to which constructors I need to define to prevent redundant constructions/destructions of objects.
Obviously, it's trivial for an int as the only member variable, but that's just for example.
Where did a third (1) come from?? (I know, the moved object should be considered invalid. Point still is it's creating 3 temporaries that I don't want.)
Edit 2:
Only potential fix I can think of would be to add another layer of indirection i.e. making it a vector<pointer>.
emplace_back() is resizing the vector which is why you get extra ~Derived() called as part of the resizing. To avoid the resizing use .reserve() to allocate memory for the specified number of objects. Note that where a type is used that uses allocated memory then you'd use std::move() with && and also & and && constructors for Base. Consider:
Riiight, I totally forgot that the vector would need to resize. Thanks.
Still, I'm kinda bummed that I even need to "manually" call reserve and emplace_back. I would prefer if there was a way to make the original code work w/o creating extra copies:
But this does throw out the option of an Initialization List.
C++ 11 might have an option to load from std::initializer_list, but that's more work than I usually feel like putting in.
In this case, since Derived has a non-explicit constructor taking just one int, you're allowed to write
std::vector<Derived> deriveds = { 42, 43, 44 };
I was messing around with this late yesterday, and found that GCC alone calls the iterator-based constructor, #5 in cppreference, to construct the vector from a pair of const int*. As such it doesn't create any extra derived objects and doesn't need to reallocate anything. https://en.cppreference.com/w/cpp/container/vector/vector.html
I found this surprising. I thought the compiler had to make an initializer_list<Derived> from the { 42, 43, 44 } and then copy the contents of the initializer_list into the vector. Clang + MSVC seem to behave this way.
I wonder if the different behavior is due to the library, or due to the compiler.