[英]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{}
時,它們都不能作為候選函數。 所以,程序應該是格式錯誤的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.