Durning the weekend I’m trying to refresh my c++ skills and learn some c++11, I’ve stumbled onto the following problem: I cannot force my container class to properly use move constructor:
I have a builder class, which is defined as follows:
class builder
{
...
container build() const
{
std::vector<items> items;
//... fill up the vector
return container(items); //should move the vector right? wrong!
//return container(std::move(items)); also doesn't work
}
}
And classes item and container, defined as follows:
class container
{
public:
container(std:vector<item> items)
: items_(items) // always invokes copy constructor on vector, never move
{ }
container(container&& rhs)
{
...
}
...
private:
std::vector<item> items_;
}
class item
{
public:
//move .ctor
item(item && rhs);
item& operator=(item && rhs);
//copy .ctor
item(const item& rhs); //this gets called instead of move .ctor
item& operator=(const item& rhs);
...
}
Now my code simply uses
builder my_builder;
...
auto result = my_builder.build();
which causes every item to be first constructed and then copied…
How should I write following classess to not copy items? Should I just go back to using standard pointers?
Your code should be changed to this:
In general: if you want your own copy of something then make that copy on that parameter list and move it to where it needs to be. Let the caller be the one that decides if they are going to copy or move the existing data. (In other words, you were halfway there. Now just move your data.)
Also:
return container(std::move(items));. I didn’t mention this before because I mistakenly thought all local variables were automatically moved in a return statement, but only the returned value is. (So this should actually work:return items;, becausecontainer‘s constructor is notexplicit.)