Reputation: 16559
"Theory" question if you will.
In order to execute/make use of the move constructor in a class, do I always have to use std::move(...)
to tell the compiler that I wish to 'move' an object rather than copy it?
Are there any cases where the compiler will invoke the move constructor for me without the use of std::move
? (My guess would be in function return values?)
Upvotes: 2
Views: 439
Reputation: 3527
std::move
is just a cast.
unique_ptr<int> global;
auto v = unique_ptr<int>(global); // global is a lvalue, therefore the
unique_ptr(unique_ptr<T>&v) constructor that accepts lvalue references is called.
auto v = unique_ptr<int>(std::move(global)); // move returns a &&rvalue reference, therefore the
unique_ptr(unique_ptr<T>&&v) constructor that accepts &&rvalue references is used.
When the criteria for elision of a copy operation are met and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
therefore,
unique_ptr<int> hello()
{
unique_ptr<int> local;
return local;
// local is an lvalue, but since the critera for elision is met,
// the returned object is created using local as if it was an rvalue
}
Also,
unique_ptr<int> hello = std::unique_ptr<int>();
// we have a pure rvalue in the right, therefore no std::move() cast is needed.
Upvotes: 1
Reputation: 42828
The compiler will invoke the move constructor without std::move
when:
In all other cases, use std::move
. E.g.:
struct S {
std::string name;
S(std::string name) : name(std::move(name)) {}
};
and
std::unique_ptr<Base> func() {
auto p = std::make_unique<Derived>();
return std::move(p); // doesn't work without std::move
}
Upvotes: 4
Reputation: 3779
According to cppreference.com (http://en.cppreference.com/w/cpp/language/move_constructor):
The move constructor is called whenever an object is initialized from xvalue of the same type, which includes
- initialization, T a = std::move(b); or T a(std::move(b));, where b is of type T;
- function argument passing: f(std::move(a));, where a is of type T and f is void f(T t);
- function return: return a; inside a function such as T f(), where a is of type T which has a move constructor.
In most cases, yes std::move
is needed.
Upvotes: 4