Using std::list
supporting move semantics as an example.
std::list<std::string> X;
... //X is used in various ways
X=std::list<std::string>({"foo","bar","dead","beef"});
The most straightforward way for compiler to do the assignment since C++11 is:
- destroy
X
- construct
std::list
- move
std::list
toX
Now, compiler isn't allowed to do following instead:
- destroy X
- contruct
std::list
in-place
because while this obviously saves another memcpy
it eliminates assignment. What is the convenient way of making second behaviour possible and usable? Is it planned in future versions of C++?
My guess is that C++ still does not offer that except with writing:
X.~X();
new(&X) std::list<std::string>({"foo","bar","dead","beef"});
Am I right?
You can actually do it by defining operator= to take an initializer list. For std::list, just call
In your case, what was happening is actually:
On most objects, such as std::list, this won't actually be expensive compared to simply constructing an object.
However, it still incurs additional allocations for the internal storage of the second std::list, which could be avoided: we could reuse the internal storage already allocated for X if possible. What is happenning is:
Some objects overload the assignment operator to take an initializer list, and it is the case for std::vector and std::list. Such an operator may use the storage already allocated internally, which is the most effective solution here.
// Please insert the usual rambling about premature optimization here