2017-07-26 37 views
0

今天我發現這個代碼不工作,因爲我期望它的工作。 根據我對L值的知識,應該調用複製構造函數,而對於R值,應該選擇移動構造函數。否則,std::move的目的實際上什麼都不做,只能投射到R值。我期待return obj將調用複製構造函數,但它調用移動。 我知道這裏的副本是無用的,但這是關於規則的。如果我的拷貝構造函數有副作用,那就是我的情況(我知道它不應該,但從技術上說它可以 - 例如:std :: cout調用)。 有沒有什麼標準允許這種行爲?另外我怎樣才能強制複製?移動構造函數返回而不是複製

#include <iostream> 

class X 
{ 
public: 
    X() = default; 

    X(const X& r): i(r.i) 
    { 
     std::cout << "copy ctor" << std::endl; 
    } 

    X(const X&& r): i(r.i) 
    { 
     std::cout << "move ctor" << std::endl; 
    } 
    int i = 0; 
}; 

X foo() 
{ 
    X obj; 
    obj.i = 10; 
    return obj; 
} 

int main() 
{ 
    X x = foo(); 
} 

移動構造函數

移動構造函數

回答

1

cppreference(重點煤礦):

如果[返回的表達]是一個左值表達式和所要求的條件除了[返回的表達式]命名函數參數th之外,複製elision被滿足或將被滿足en重載解析選擇用於初始化返回值的構造函數執行兩次:第一個就像[返回的表達式]是一個右值表達式(因此它可以選擇移動構造函數或參考const的複製構造函數) ,如果沒有合適的轉換可用,則第二次使用lvalue [返回的表達式]執行重載解析(因此它可以選擇引用非const的複製構造函數)。 上述規則適用,即使該函數的返回類型爲類型不同[返回式(複製省略需要同一類型)

長話短說,return隱含試圖打動你回什麼讓當感。它只會作爲最後的手段進行復制(例如,不提供移動構造函數)。

+0

它實際上很奇怪,它可能默默地複製,如果你明確要求移動,並可能移動,如果你沒有:) – incognito

+0

謝謝你的解釋 – incognito

+0

@incognito的確。這就是爲什麼你應該仔細設計你的課程;) – Quentin