"理论"如果你愿意的话。
为了在类中执行/使用移动构造函数,我是否总是必须使用std::move(...)
来告诉编译器我希望移动'一个对象而不是复制它?
在没有使用std::move
的情况下,编译器是否会为我调用移动构造函数? (我的猜测是函数返回值?)
答案 0 :(得分:3)
根据cppreference.com(http://en.cppreference.com/w/cpp/language/move_constructor):
只要从相同类型的xvalue初始化对象,就会调用移动构造函数,其中包括
- 初始化,T a = std :: move(b);或者T a(std :: move(b));,其中b是T的类型;
- 函数参数传递:f(std :: move(a));,其中a是T类型,f是void f(T t);
- 功能返回:返回a;在诸如T f()之类的函数内部,其中a是T类型,它具有移动构造函数。
在大多数情况下,需要std::move
。
答案 1 :(得分:2)
在以下情况下,编译器将调用不带std::move
的移动构造函数:
在所有其他情况下,请使用std::move
。 E.g:
struct S {
std::string name;
S(std::string name) : name(std::move(name)) {}
};
和
std::unique_ptr<Base> func() {
auto p = std::make_unique<Derived>();
return std::move(p); // doesn't work without std::move
}
答案 2 :(得分:1)
std::move
只是演员。
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.
当满足复制操作的省略标准并且要通过左值指定要复制的对象时,首先执行的重载决策以选择复制的构造函数,就好像该对象由 右值指定。
因此,
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
}
此外,
unique_ptr<int> hello = std::unique_ptr<int>();
// we have a pure rvalue in the right, therefore no std::move() cast is needed.