[英]Behavioral differences with std::move(*this) from a member function
鑒於類定義:
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()
的用例可能是什么。
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 state
Apply
的原始版本本身不做任何事情,但它可以啟用其他功能。 例如,假設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 m2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.