在这种情况下是否会移动一个值
Will a value be moved in this case
考虑以下片段:
class Bar {...};
class Foo {
public:
Foo(const Bar& bar): bar_(bar) {}
private:
Bar bar_;
};
int main() {
Foo foo({...}); // Passing an rvalue Bar object here.
}
问题:我生成的对象会被复制到Foo的构造函数中,还是会被移动?更准确地说,以下哪项是正确的?
- 它会一直被复制。
- 它会一直移动(我很确定不是这样)。
- 这是未指定的行为。
It will be copied always.
您创建的 rvalue
绑定到一个 const 左值引用。但即使它绑定到右值引用,您也可以从左值 (bar
) 构造 bar_(bar)
。
绑定到引用的对象的值类别没有实际意义,重要的是引用本身的值类别。就像已经提到的,表达式 bar
是一个左值。
作为一般且有些粗略的经验法则,每个作为某物名称的表达式都是左值。
如果你想在一个构造函数中同时支持移动和复制,前进的方法是:
Foo(Bar bar): bar_(std::move(bar)) {}
现在 bar
可以通过移动或复制来构建,具体取决于来源,并且您的成员是从您可以安全地移出的对象构建的。这当然总是会导致额外的移动。如果你想避免它,那么需要两个c'tors:
Foo(const Bar& bar): bar_(bar) {}
Foo(Bar&& bar): bar_(std::move(bar)) {}
考虑以下片段:
class Bar {...};
class Foo {
public:
Foo(const Bar& bar): bar_(bar) {}
private:
Bar bar_;
};
int main() {
Foo foo({...}); // Passing an rvalue Bar object here.
}
问题:我生成的对象会被复制到Foo的构造函数中,还是会被移动?更准确地说,以下哪项是正确的?
- 它会一直被复制。
- 它会一直移动(我很确定不是这样)。
- 这是未指定的行为。
It will be copied always.
您创建的 rvalue
绑定到一个 const 左值引用。但即使它绑定到右值引用,您也可以从左值 (bar
) 构造 bar_(bar)
。
绑定到引用的对象的值类别没有实际意义,重要的是引用本身的值类别。就像已经提到的,表达式 bar
是一个左值。
作为一般且有些粗略的经验法则,每个作为某物名称的表达式都是左值。
如果你想在一个构造函数中同时支持移动和复制,前进的方法是:
Foo(Bar bar): bar_(std::move(bar)) {}
现在 bar
可以通过移动或复制来构建,具体取决于来源,并且您的成员是从您可以安全地移出的对象构建的。这当然总是会导致额外的移动。如果你想避免它,那么需要两个c'tors:
Foo(const Bar& bar): bar_(bar) {}
Foo(Bar&& bar): bar_(std::move(bar)) {}