2014-10-01 32 views
0

我嘗試用函數的返回值初始化實例。我預計它會調用移動構造函數,但結果不是。看來,返回值直接由實例t接管。因爲函數中的t和返回值是相同的地址。編譯器是否優化了這種情況?C++函數返回的值是一個右值嗎?無法使用複製/移動構造函數初始化實例

我的環境是Mac OS X的小牛,默認克++ -std = C++ 11

class T1 { 
public: 
    T1() { 
    printf("T1::constructor\n"); 
    t = new char[100]; 
    } 
    T1(const T1 &another) { 
    printf("T1::copy_constructor\n"); 
    } 
    T1(T1 &&another) { 
    printf("T1::move_constructor\n"); 
    } 
    char *t; 
}; 

T1 func() { 
    T1 t; 
    printf("add:%d\n", static_cast<void*>(&t)); 
    return t; 
} 

void rref_test() { 
    T1 t = func(); 
    T1 t2 = std::move(t); 
    printf("add:%d\n", static_cast<void*>(&t)); 
} 


int main() { 
    rref_test(); 

    return 0; 
} 
+0

請澄清一下您的問題。你期望輸出什麼,你會得到什麼? – juanchopanza 2014-10-01 05:48:23

回答

3

這取決於返回類型。如果返回類型是一個左值引用,那麼函數調用表達式是一個左值,否則它是一個右值。

當你寫T1 t = func();,func()是一個右值。然而,這種情況是copy elision的候選人,這就是爲什麼你沒有看到任何複製構造函數或移動構造函數調用。

對於T1 t2 = std::move(t);您應該看到對移動構造函數的調用。

一些編譯器具有切換以禁用複製刪除,例如,用gcc它是-fno-elide-constructors

相關問題