[英]Why does compiler use move constructor instead of the copy constructor
下面的代碼可以嗎
#include <iostream>
struct Foo
{
Foo() { std::cout << "Foo::Foo" << std::endl; }
~Foo() { std::cout << "Foo::~Foo" << std::endl; }
Foo(const Foo&) { std::cout << "Foo::Foo(const Foo&)" << std::endl; }
Foo& operator=(const Foo&) { std::cout << "Foo::operator=(const Foo&)" << std::endl; return *this; }
Foo(Foo&&) { std::cout << "Foo::Foo(Foo&&)" << std::endl; }
Foo& operator=(Foo&&) { std::cout << "Foo::operator=(Foo&&)" << std::endl; return *this; }
};
Foo foo()
{
Foo second;
return second;
}
int main()
{
foo();
}
產生這樣的輸出:
Foo::Foo
Foo::Foo(Foo&&)
Foo::~Foo
Foo::~Foo
為什么調用移動構造函數而不是復制構造函數?
答案僅僅是因為該標准是這樣說的。 第12.8節第32段:
當滿足復制/移動操作的省略標准,但不滿足異常聲明的標准,並且要復制的對象由左值指定時,或者當return語句中的表達式為(可能帶有括號)id-用最內層封閉函數或lambda-expression的主體或參數聲明子句聲明的具有自動存儲持續時間的對象的表達式,首先執行重載解析以選擇副本的構造函數,就好像該對象由右值指定。
基本上就是全部。 從邏輯上講,如果該變量具有自動存儲期限,並且您return
其return
,則在返回后立即在清理本地作用域時不再存在該變量。 這就是為什么即使它是一個左值,它也非常類似於一個右值。 因為從技術上講它仍然是左值,所以必須在標准中明確地指定此異常,在這里就可以了。 請注意,這整個情況特定於從函數return
,並且一般不包括范圍結尾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.