Reputation: 1078
If you are making a copy of something to store in a class, like this:
struct S {
S(std::vector<int> v);
private:
std::vector<int> m; // gonna store v in here
};
I have heard you're supposed to let the compiler make the copy for you by taking v
by value because it can do it more efficiently sometimes. However, in the member initialization list of the constructor, should you initialize m
with v
or std::move(v)
? What if the type of v
is a move-only type? (In the latter case I assume you must use move
.)
Upvotes: 1
Views: 68
Reputation:
If it's move-only, then yes your best course of action is to take the argument by value, then move.
When the type of v could be copyable or movable, I'd describe the state of the "best practice" as somewhat fluid and there are different schools of thought at the moment. But this, I think, is being accepted as the way to write optimal move-aware constructors such as you require.
I would say, do what you've done here, and yes initialise the member from an rvalue using a move cast.
When you USE the constructor, try and take advantage of copy-elision. For example, this:
struct S {
S(std::vector<int> v) : m(std::move(v)) {}
private:
std::vector<int> m;
};
std::vector<int> create_vector()
{
std::vector<int> vec = // initialisation stuff
return vec;
}
int main()
{
S instance_of_s{create_vector()};
return 0;
}
... should ideally not copy anything at all due to various copy-elisions. But of course, this is compiler dependent.
Here's an example which demonstrates this.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class VectorWrapper
{
public:
VectorWrapper() : vec(){}
VectorWrapper(const VectorWrapper& other) : vec(other.vec){ cout << "COPY" << endl; }
VectorWrapper(VectorWrapper&& other) : vec(move(other.vec)){ cout << "MOVE" << endl; }
private:
vector<int> vec;
};
struct S
{
S(VectorWrapper v) : m(move(v)) {}
private:
VectorWrapper m;
};
int main()
{
S instance_of_s{VectorWrapper()};
return 0;
}
Under GCC 4.7.2 the output is:
MOVE
References:
http://cpptruths.blogspot.co.uk/2012/03/rvalue-references-in-constructor-when.html
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
(Note that this is a series of articles, I missed the link for that to start with!)
Upvotes: 1