2016-05-13 51 views
2

我有一個類,移動任務被明確刪除,因爲對象不應該是可移動的。但是,如果我分配到使用這個RVO類的一個實例,編譯器給我的錯誤:編譯器不會使用複製分配而是移動?

main.cpp:12:16: note: candidate function has been explicitly deleted 

也編譯器提現有的拷貝賦值運算符,但不使用它。

這裏是我的代碼(或(不)運行例如here):

class foo { 
public: 
    foo() {} 
    foo(foo const& r) {} 
    foo(foo&&) = delete; 

    foo const& operator=(foo const& r) { return *this; } 
    foo const& operator=(foo&& r) = delete; 
}; 

int main(int argc, char **argv) { 
    foo bar; 
    bar = foo(); 
    return 0; 
} 

我發現了一個非常類似的帖子here

我知道我可以通過使用臨時避免這種情況。我想知道爲什麼每個編譯器(我用gcc,clang和vs2013測試過)不能直接調用現有的拷貝任務?有什麼我失蹤?

+4

此舉賦值運算符是一個更好的匹配。在考慮它被刪除之前發生這種情況。 – chris

+4

刪除的函數參與重載解析。 – 101010

+0

只要不刪除移動assingment,一切都會很好。不動的存在會抑制默認值。 – SergeyA

回答

2

複製分配未被調用,因爲(刪除的)移動分配與重載分辨率更匹配。

根本不要聲明移動分配。然後複製分配將被選中。隱式移動賦值運算符將不會生成,因爲該類具有用戶聲明的複製構造函數,移動構造函數和複製賦值運算符。任何這些都將阻止生成隱式移動賦值運算符。


But if i assign to an instance of this class using RVO

沒有這裏涉及視網膜靜脈阻塞。您創建一個臨時foo並將其複製分配給一個現有的變量。複製分配不能被刪除。

另外,從賦值運算符返回值是非常不尋常和低效的。

+0

'另外,從賦值運算符返回值是非常不尋常和低效的。'這是真的,也是來自erip的評論('公司喜歡慢速代碼')。我正在圍繞一個不是我設計的課程而只是想知道爲什麼會發生這樣的事情...... – user1810087

0

你可以使用新的安置要做到這一點:

#include <iostream> 
#include <string> 
#include <new> 

class foo { 
public: 

    foo() {} 
    foo(foo const& r) {} 
    foo(foo&&) = delete; 

    foo const& operator=(foo const& r) { return *this; } 
    foo const& operator=(foo&& r) = delete; 
}; 

int main(int argc,char **argv) 
{ 
    foo bar; 

    //bar = foo(); 
    bar.~foo(); 
    new(&bar) foo(); 

    return 0; 
} 
相關問題