在***评论的行中,为什么要调用Bar的复制构造函数? input_bar
是一个右值引用,所以我希望调用move构造函数。它转换为左值参考吗?如果我将该行更改为bar_(std::move(input_bar))
,我可以进行移动构造函数调用。
#include <iostream>
#include <array>
#include <memory>
class Bar
{
public:
Bar(const Bar& bar)
{
std::cout << "copy constructor called" << std::endl;
}
Bar(Bar&& bar)
{
std::cout << "move constructor called" << std::endl;
}
};
class Foo
{
public:
Foo(Bar&& input_bar) :
bar_(input_bar) // ***
{
}
Bar bar_;
};
int main()
{
Bar bar;
Foo foo(std::move(bar));
return 0;
}
答案 0 :(得分:9)
一旦实体有名字,它显然是一个左右!如果您有rvalue引用的名称,则名称为不的实体为右值,但为左值。重点是你知道这个实体引用了一个右值,你可以合法地移动它的内容。
如果您想将右值转发到您调用的下一个函数,则可以使用std::move()
,例如:
Foo(Bar&& bar): bar_(std::move(bar)) {}
没有std::move()
,rvalue被认为是构造函数所有。使用std::move()
,它会释放所有权并将其传递给下一个函数。
答案 1 :(得分:2)
你必须移动rhrs:
Foo(Bar&& input_bar) :
bar_(std::move(input_bar)) // ***
{
}
理由是,一旦我们实际使用RHR,它应该被人为地视为超出范围。强制您使用std::move
允许以下代码未定义:
Foo(Bar&& input_bar) {
std::cout << input_bar.baz << std::endl;//not undefined
bar_ = Bar{std::move(input_bar)};//input_bar is now essentailly destroyted
//std::cout << input_bar.baz << std::endl;//Undefined behavior, don't do this
}
一般的经验法则是,只有没有名字的东西实际上可以用作RHR ...... RHR作为参数有名字,因此将被视为LHR,直到你调用它们的函数。