簡體   English   中英

將默認賦值運算符聲明為constexpr:哪個編譯器是對的?

[英]Declaring defaulted assignment operator as constexpr: which compiler is right?

考慮

struct A1 {
    constexpr A1& operator=(const A1&) = default;
    ~A1() {}
};
struct A2 {
    constexpr A2& operator=(const A2&) = default;
    ~A2() = default;
};
struct A3 {
    ~A3() = default;
    constexpr A3& operator=(const A3&) = default;
};

GCC和MSVC接受所有三種結構。 Clang拒絕A1A2 (但接受A3 ),並顯示以下錯誤消息:

 <source>:2:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A1& operator=(const A1&) = default; ^ <source>:6:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A2& operator=(const A2&) = default; ^ 2 errors generated. 

現場演示

哪個編譯器是正確的,為什么?

我認為所有三個編譯器都是錯誤的。

[dcl.fct.def.default] / 3說:

未定義為已刪除的顯式默認函數只有在被隱式聲明為constexpr時才可以聲明為constexprconsteval 如果函數在其第一個聲明中顯式默認,則隱式聲明將隱式地認為是constexpr

何時復制賦值運算符隱式聲明constexpr [class.copy.assign] / 10

隱式定義的復制/移動賦值運算符是constexpr if

  • X是文字類型,和
  • [...]

文字類型的位置,來自[basic.types] / 10

類型是文字類型,如果它是:

  • [...]
  • 一個可能具有cv限定的類類型,它具有以下所有屬性:

    • 它有一個簡單的析構函數,
    • [...]

A1沒有簡單的析構函數,因此它的隱式復制賦值運算符不是constexpr 因此,復制賦值運算符格式不正確(gcc和msvc錯誤接受)。

另外兩個很好,這是拒絕A2的鏗鏘聲。


注意我引用的[dcl.fct.def.default]的最后一位。 如果您明確默認,則實際上不必添加constexpr 在可行的情況下隱含着constexpr

C ++ 17標准規定:

15.8.2復制/移動賦值運算符[class.copy.assign]
...

10對於默認且未定義為已刪除的類X的復制/移動賦值運算符,在使用odr時會隱式定義(6.2)(例如,當通過重載決策選擇它以分配給其類類型的對象時) )或在第一次聲明后明確違約時。 隱式定義的復制/移動賦值運算符是constexpr if
(10.1) - X是文字類型,和
(10.2) - 選擇復制/移動每個直接基類子對象的賦值運算符是constexpr函數,和
(10.3) - 對於類型(或其數組)的X每個非靜態數據成員,選擇復制/移動該成員的賦值運算符是constexpr函數。

復制賦值運算符在兩種情況下滿足上述要求。 在第一種情況下,由於非平凡的析構函數,我們有一個非文字類型。

所以我認為Clang在第二種情況下拒絕代碼是錯誤的。

有一個提交Clang的錯誤標題: 默認的析構函數阻止在默認的復制/移動操作符上使用constexpr,它顯示與OP中的代碼相同的症狀。

錯誤報告的評論說明:

當默認的析構函數被注釋掉(即沒有用戶聲明)時,錯誤就不復存在了。

如果在復制賦值運算符之前聲明析構函數,問題也會消失。

對於問題中的代碼也是如此。

正如@YSC所指出的,這里的另一個相關引用是: [dcl.fct.def.default] / 3 ,其中說明:

未定義為已刪除的顯式默認函數只有在被隱式聲明為constexpr時才可以聲明為constexprconsteval 如果函數在其第一個聲明中顯式默認,則隱式聲明將隱式地認為是constexpr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM