簡體   English   中英

為什么編譯器使用move構造函數而不是copy構造函數

[英]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的主體或參數聲明子句聲明的具有自動存儲持續時間的對象的表達式,首先執行重載解析以選擇副本的構造函數,就好像該對象由右值指定。

基本上就是全部。 從邏輯上講,如果該變量具有自動存儲期限,並且您returnreturn ,則在返回后立即在清理本地作用域時不再存在該變量。 這就是為什么即使它是一個左值,它也非常類似於一個右值。 因為從技術上講它仍然是左值,所以必須在標准中明確地指定此異常,在這里就可以了。 請注意,這整個情況特定於從函數return ,並且一般不包括范圍結尾。

second是從foo返回的,並且作為本地對象被視為右值(感謝Nir Friedman的正確解釋 )。 返回的Foo對象是從臨時對象構造的,該臨時對象綁定到move構造函數。

現代編譯器應跳過move構造函數調用,並使用復制省略( demo )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM