Below is some code that contains some already created Location objects and updates them. Then it needs to construct a std::vector of those objects to pass to other functions.
The way I construct the vector looks cleaner as it is a initializer list and is one line, instead of using 3 push_back calls after initializing an empty vector. Since we know all the elements that are going in to the vector already at construction time.
However, this leads to 2 copies being made per element. Firstly, why are there two copies being made in this line? Is the initializer list first constructor with copies, and then the vector constructor is called, therefore a second copy?
std::vector<Location> pointsVec {l1, l2, l3};
And secondly, is there a vector constructor or another technique to initialize the vector with only 1 copy? (I want to make exactly 1 copy as I still want to use the local objects)
struct Location
{
Location(int x, int y, std::string frame)
: x(x)
, y(y)
, frame(std::move(frame))
{
std::cout << "ctor" << std::endl;
}
Location(const Location & other)
: x(other.x)
, y(other.y)
, frame(other.frame)
{
std::cout << "copy ctor" << std::endl;
}
Location(Location && other)
: x(std::move(other.x))
, y(std::move(other.y))
, frame(std::move(other.frame))
{
std::cout << "move ctor" << std::endl;
}
int x;
int y;
std::string frame;
};
int main ()
{
// local objects
Location l1 {1, 2, "local"};
Location l2 {3, 4, "global"};
Location l3 {5, 6, "local"};
// code that updates l1, l2, l3
// .
// .
// .
// construct vector
std::vector<Location> pointsVec {l1, l2, l3}; // 2 copies per element
std::vector<Location> pointsVec1;
pointsVec1.push_back(l1);
pointsVec1.push_back(l2);
pointsVec1.push_back(l3); // 1 copy per element
return 0;
}
edit: this question was in general for objects that are expensive to copy. adding a string to this struct to demonstrate that point
edit: adding sample move ctor