2013-03-18 145 views
21

我有以下代碼析構函數的unique_ptr

class A { 
    public: 
     A(){} 
     ~A(){} 
    private: 
     std::vector<std::unique_ptr<double> > x; 
}; 

A f() { 
    A a; 
    return a; 
} 

int main() { 
    A a=f(); 
    return 0; 
} 

它沒有編譯器(gcc 4.7),除非我註釋掉析構函數。實際上,我並不需要在代碼中使用這個析構函數,我只是想將其用於調試目的。

但是,我不明白髮生了什麼,因此我擔心我做錯了什麼。這裏發生了什麼?

+4

當詢問爲什麼某些東西不能編譯時,包含錯誤信息總是有幫助的。 – NPE 2013-03-18 20:07:10

+0

@ user2183861不,它沒有在那裏回答。這個問題完全不同 – 2013-03-19 07:12:15

回答

26

這是因爲顯式定義的析構函數的存在阻止了A的移動構造函數的隱式生成。

每款C++ 11標準的12.8/9:

如果一個類X的定義不明確宣佈此舉的構造函數,一個將被隱式聲明 欠繳當且僅當

- X沒有一個用戶聲明的拷貝構造函數,

- X沒有一個用戶聲明的拷貝賦值運算符,

X沒有一個用戶聲明的舉動賦值運算符,

- X沒有一個用戶聲明的析構函數,並

- 此舉構造不會被隱式地刪除定義。

現在沒有移動構造函數,返回從f()編譯器將嘗試調用隱式生成的拷貝構造函數(目前仍在向後兼容性產生)的值。但是,std::unique_ptr是不可複製的。因此,錯誤。

將明確定義移動構造函數(或聲明一個爲默認值,如註釋中的juanchopanza所示)將解決該問題。

+8

+1,加上'A(A &&)= default;'會讓它編譯。 – juanchopanza 2013-03-18 20:07:57

+0

@juanchopanza:是的,正確 – 2013-03-18 20:09:24

+0

好的謝謝,這解決了它;) – 2013-03-18 20:10:43