2014-04-10 60 views
4

下面的代碼失敗,GCC 4.8.0(MinGW的-W64)與-O2 -std = C++ 11個-frtti -fexceptions -mthreadsC++刪除移動賦值運算符編譯問題

#include <string> 

class Param 
{ 
public: 
    Param() : data(new std::string) { } 

    Param(const std::string & other) : data(new std::string(other)) { } 

    Param(const Param & other) : data(new std::string(*other.data)) { } 

    Param & operator=(const Param & other) { 
     *data = *other.data; return *this; 
    } 

    ~Param() { 
     delete data; 
    } 

    Param & operator=(Param &&) = delete; 


private: 
    std::string * data; 
}; 


int main() 
{ 
    Param param; 
    param = Param("hop"); 


    return 0; 
} 

隨着錯誤:錯誤:使用刪除功能「帕拉姆&帕拉姆::運算符=(帕拉姆& &)」 就行了:

param = Param("hop");

,編制好如果我刪除了移動作業中刪除線。

不應該有默認的舉動賦值運算符,因爲有用戶定義的複製構造函數,用戶定義的拷貝賦值和析構函數,所以刪除它不應該影響編譯,爲什麼會失敗? 爲什麼分配只是不使用複製分配?

+1

我不會對你的問題發表評論,只是說你使用你的構造函數是錯誤的。你應該使用構造函數的初始化列表,如下所示:'Param():data(new std :: string){}'因爲否則你做了一些奇怪的初始化然後賦值。 – noobProgrammer

+0

OK,我做了一些改變的代碼來解決一些錯誤和回答您的意見,但這並不改變結果 – galinette

+3

'= delete'意味着「調用這個函數是一個錯誤」,從重載集合不是「刪除此功能「。 – Casey

回答

7

刪除的功能正是你嘗試main使用賦值運算符。通過明確地將其定義爲刪除你聲明它,並在同一時間使用它是一個錯誤說。所以當你嘗試從一個右值(Param("hop"))賦值時,編譯器首先查看是否聲明瞭一個移動賦值操作符。既然它是最好的匹配,它會嘗試使用它,只是爲了發現它已被刪除。因此錯誤。

下面是這個機制沒有使用特殊功能的另一個例子:

class X 
{ 
    void f(int) {} 
    void f(short) = delete; 
}; 

int main() 
{ 
    X x; 
    short s; 
    x.f(s); // error: f(short) is deleted. 
} 

刪除刪除f(short)會導致編譯器選擇非刪除f(int),因此編譯沒有錯誤。

+3

好吧,我用了錯誤的話,現在修復。但是對於賦值,移動語義不應該被要求,否則它會破壞C++ 99代碼。它應該回退到複製分配。如果我不刪除它,沒有默認的移動分配應該在那裏。 – galinette

+0

@galinette:查看編輯的答案。 – celtschk

+2

爲什麼這個評論仍然是upvotes,儘管提到我的答案*舊*版本,並根本不適合*當前版本? – celtschk