2015-12-09 136 views
11

有沒有理由使用「規範」簽名operator=如何禁止轉讓

class X { 
    X& operator=(const X&) = delete; 
    X& operator=(X&&) = delete; 
}; 

,而不是僅僅

class X { 
    void operator=(X) = delete; 
}; 

時,所有你想要做的是delete呢?

UPD:
此外,考慮以下情況,當X有一個顯式聲明的移動或拷貝構造函數。

class X { 
public: 
    X(X&&); 
}; 

在這種情況下op=(X&&)op=(const X&)被隱式刪除,但我想明確地表達分配是不允許的。

+0

您的版本是否正常工作?編譯器沒有自己定義該版本,因此刪除它不應該有任何作用。 –

+0

@MarkRansom你可以刪除任何你想要的。它不是'= default' – Abyx

+2

爲什麼你需要刪除第一個例子中的複製和移動賦值操作符? 'X&operator =(const X&)= delete;'單獨應該夠了,不是?移動賦值運算符不會由於用戶聲明的複製賦值運算符而隱式聲明。 – Praetorian

回答

6

不,沒有技術上的理由使用規範的複製分配操作符簽名。

如在標準看出,[dcl.fct.def.delete]§8.4.3:

  • 引用到已刪除的隱函數的程序或明確地說,除了宣佈它外,是不合格的。 [注意:這包括隱式或顯式地調用該函數並形成指向函數的指針或成員指針 。它甚至適用於沒有進行潛在評估的表達式中的引用。 如果函數 被重載,則僅在通過重載解析選擇函數時才引用它。 - 注完]
  • 因此被刪除的功能的名稱,在這種情況下operator=,可以僅當編譯器發現一個優選的過載分辨率使用。然而,這樣的過載不可能存在,因爲Xconst X&與參數([over.ics.rank]§13.3.3.2)無法區分,並且返回值被忽略。

    這就是說,有使用規範簽名的文體原因。僅存在這個問題的事實表明,任何人閱讀你的代碼可能而不是知道的意義,並認爲它是做一些特殊的事情。爲了便於閱讀,我建議您使用熟悉的X& operator=(const X&) = delete;