给定类定义:
struct MoveOnly
{
MoveOnly(int v_)
: v(v_)
{
std::cout << ((void*)this) << " MoveOnly " << v << "\n";
}
~MoveOnly()
{
std::cout << ((void*)this) << " ~MoveOnly " << v << "\n";
}
MoveOnly(const MoveOnly&) = delete;
MoveOnly& operator=(const MoveOnly&) = delete;
MoveOnly(MoveOnly &&src)
{
v = std::exchange(src.v, -1);
std::cout << ((void*)this) << " MoveOnly&& " << v << "\n";
}
MoveOnly& operator=(MoveOnly&&) = default;
MoveOnly&& Apply()
{
std::cout << ((void*)this) << " Apply " << v << "\n";
return std::move(*this);
}
int v;
};控制台显示代码:
auto m1 = MoveOnly(1);
m1.Apply();
> 0x7fff5fbff798 MoveOnly 1
> 0x7fff5fbff798 Apply 1
> 0x7fff5fbff798 ~MoveOnly 1现在,如果我将Apply更改为返回值而不是r值引用:
MoveOnly Apply()
{
std::cout << ((void*)this) << " Apply " << v << "\n";
return std::move(*this);
}我明白了:
auto m1 = MoveOnly(1);
m1.Apply();
> 0x7fff5fbff798 MoveOnly 1
> 0x7fff5fbff798 Apply 1
> 0x7fff5fbff790 MoveOnly&& 1
> 0x7fff5fbff790 ~MoveOnly 1
> 0x7fff5fbff798 ~MoveOnly -1第一个示例似乎保留了原始对象,这违背了我对std::move所做的事情的直觉。尽管它没有调用move构造函数,但我可以看到原始对象仍然有一个1。
我在这里试图弄清楚的是,C++标准是如何解释这种行为的,以及不同版本的Apply()的用例可能是什么。
发布于 2017-03-20 07:23:41
std::move不会“做”任何事情。它所做的就是将一个左值转换成一个右值。示例:
class Foo { ... };
void leave(Foo && f) {}
void take(Foo && f) { auto g = std::move(f); }
Foo f;
leave(f); // this won't compile, bar wants an rvalue
leave(std::move(f)); // this compiles, but f is not changed in any way
take(std::move(f)); // compiles, and leaves f in the moved from stateApply的原始版本本身不能做任何事情,但它可以实现其他功能。例如,假设Apply的原始定义
auto m1 = MoveOnly(1);
m1.Apply(); // does nothing
auto m2 = m1; // doesn't compile
auto m2 = m1.Apply() // Does compile, and does something! moves m1 to m2https://stackoverflow.com/questions/42893456
复制相似问题