在C ++ 17中分配给数组

M.M*_*M.M 5 c++ arrays variable-assignment language-lawyer c++17

这是一些代码:

int main()
{
    using T = int[3];
    T a;
    a = T{};
}
Run Code Online (Sandbox Code Playgroud)

据我所知,根据C ++ 17标准,此代码是正确的,但是我尝试的每个编译器都拒绝了它。

此代码实际上不正确吗?如果是这样,该标准的哪些条款?


到目前为止,我的研究是:在C和较旧版本的C ++中,代码不正确,因为赋值运算符的左操作数必须是可修改的左值,a或者不是,或者没有明确指定。但是由于C ++ 17 a被明确指定为可修改的左值(C ++ 17 [basic.lval] / 7)。

此处未应用数组到指针的转换:[expr.ass]没有明确指定它,[expr] / 9和[expr] / 10似乎没有适用:=期望将prvalue作为正确的操作数,并提供了prvalue。(并且期望将glvalue作为左操作数,并提供了glvalue)。如果在期望有prvalue的情况下提供了glvalue,则适用这些条款,反之亦然。

[expr.ass] / 3表示将右表达式隐式转换为左操作数的类型。但是由于双方的类型相同,int[3]因此似乎不需要进行转换。

因此,我看不到任何将[expr.ass] / 2排除在外的子句,即右侧的值存储在左侧所指的对象中。


最新的草案围绕[basic.lval] / 7和[expr] / 9-10中的子句移动,但似乎并没有改变其含义,甚至将[expr.ass] / 2改为更清晰:

在简单赋值(=)中,通过用右操作数的结果替换其值来修改左操作数所引用的对象。

eer*_*ika 7

据我所知,“可修改的左值”的定义在C ++中未指定,或者有意将数组指定为可分配的(我怀疑前者是正确的,因为没有编译器会后者)。

标准(最新草案)说:

[basic.lval]

左值是可修改的,除非其类型为const限定或为函数类型。

这很简洁,但是没有排除数组。

此外,至少自C ++ 03起,这在标准版本中并未发生变化,它指定了以下内容:

[basic.lval]

11无法修改函数,但可以修改指向函数的指针。

12指向不完整类型的指针可以修改。...

13 const限定表达式的引用不得修改...

除了使用更具描述性的措辞而不是确定性的措辞外,大部分内容都相同。不排除数组。


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

6.3.2.1左值,数组和函数指示符

1 ...一个可修改的左值是没有数组类型的左值...