簡體   English   中英

在 C++17 中賦值給數組

[英]Assignment to array in C++17

這是一些代碼:

int main()
{
    using T = int[3];
    T a;
    a = T{};
}

據我所知,根據 C++17 標准,這段代碼是正確的,但是我嘗試過的每個編譯器都拒絕了它。

這段代碼實際上不正確嗎? 如果是,標准的哪些條款?


到目前為止我的調查:在 C 和舊版本的 C++ 中,代碼不正確,因為賦值運算符的左操作數必須是可修改的左值,而a要么不是,要么沒有明確指定。 但由於 C++17 a被明確指定為可修改的左值 (C++17 [basic.lval]/7)。

此處不應用數組到指針的轉換:[expr.ass] 未明確指定它,並且 [expr]/9 和 [expr]/10 似乎不適用: =期望純右值是正確的操作數,並提供了一個純右值。 (並且它期望左操作數為泛左值,並且提供了泛左值)。 如果在期望純右值的地方提供了泛左值,則這些條款適用,反之亦然。

[expr.ass]/3 表示右表達式被隱式轉換為左操作數的類型。 但由於雙方具有相同的類型int[3]似乎沒有必要進行轉換。

所以我看到沒有任何條款會排除 [expr.ass]/2 的應用,即右側的值存儲在左側引用的對象中。


最新的草案圍繞 [basic.lval]/7 和 [expr]/9-10 中的條款移動,但似乎沒有改變它們的含義,甚至將 [expr.ass]/2 重新表述為更清晰:

在簡單賦值 ( = ) 中,左操作數引用的對象通過用右操作數的結果替換其值來修改。

據我所知,“可修改左值”的定義要么在 C++ 中未指定,要么有意將數組指定為可賦值(我懷疑前者是正確的,因為沒有編譯器會執行后者)。

標准(最新草案)說:

[基本.lval]

左值是可修改的,除非它的類型是 const 限定的或者是函數類型。

這很簡潔,但不排除數組。

此外,至少從 C++03 開始​​,標准版本沒有改變,它指定了以下內容:

[基本.lval]

11 函數不能修改,但函數指針可以修改。

12 指向不完整類型的指針是可以修改的。 ...

13 const 限定表達式的所指對象不應被修改......

除了使用比確定性的措辭更具描述性之外,這幾乎是相同的。 不排除數組。


相比之下,C11 標准非常清晰(引用 N1548 草案):

6.3.2.1 左值、數組和函數指示符

1 ...可修改的左值是沒有數組類型的左值,...

因為內置運算符也受 [over.built] 管轄,即:

本小節規定了代表在條款[expr]中定義的內置運算符的候選運算符函數。

對於賦值運算符,對應函數的形式為:
over.built#19

對於每個三元組 (L, vq, R),其中 L 是算術類型,而 R 是提升算術類型,存在以下形式的候選運算符函數

對於每對 (T, vq),其中 T 是任何類型,都存在以下形式的候選運算符函數

T vq& operator=(T vq&, T*);

對於每對 (T, vq),其中 T 是一個枚舉或指向成員 type 的指針,存在以下形式的候選運算符函數

vq T& operator=(vq T&, T);

因此,當相應的參數是a, T{}時,它們都不能作為候選函數。 所以,程序應該是格式錯誤的。

正如您在 [class.temporary]/5 的注釋 3中所見,C++ 標准中沒有規定實現純右值數組,該注釋總結了這些實現的情況。

暫無
暫無

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

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