在C ++ 17中分配给数组 [英] Assignment to array in C++17
问题描述
这是一些代码:
int main()
{
using T = int[3];
T a;
a = T{};
}
据我所知,根据C ++ 17标准,此代码是正确的,但是我尝试过的每个编译器都拒绝了它.
As far as I can tell, this code is correct according to the C++17 Standard, however every compiler I tried rejected it.
此代码实际上不正确吗?如果是,那么该标准的哪些条款?
Is this code actually incorrect? If so, by what clauses of the Standard?
到目前为止我的调查:在C和较旧版本的C ++中,代码不正确,因为赋值运算符的左操作数必须是可修改的左值,即 a
否,或者没有明确指定.但是由于C ++ 17 a
被明确指定为可修改的左值(C ++ 17 [basic.lval]/7).
My investigation so far: In C and in older versions of C++, the code was incorrect because the assignment operator's left operand must be a modifiable lvalue, which a
either wasn't, or it was unclearly specified. But since C++17 a
is clearly specified as a modifiable lvalue (C++17 [basic.lval]/7).
此处未应用数组到指针的转换:[expr.ass]未明确指定它,并且[expr]/9和[expr]/10似乎不适用:=
期望将prvalue作为正确的操作数,并提供了prvalue.(并且期望将glvalue作为左操作数,并提供了glvalue).如果在期望有prvalue的情况下提供了glvalue,则这些条款适用.
The array-to-pointer conversion is not applied here: [expr.ass] doesn't explicitly specify it, and [expr]/9 and [expr]/10 don't seem to apply: the =
expects a prvalue as right operand, and a prvalue was provided. (And it expects a glvalue as left operand, and a glvalue was provided). Those clauses apply if a glvalue was supplied where a prvalue was expected or vice versa.
[expr.ass]/3说,右表达式隐式转换为左操作数的类型.但是由于双方的类型都相同,所以 int [3]
似乎没有必要进行转换.
[expr.ass]/3 says the right expression is implicitly converted to the type of the left operand . But since both sides have identical type int[3]
no conversion seems to be necessary.
因此,我没有看到任何将[expr.ass]/2排除在外的子句,即右侧的值存储在左侧所指的对象中.
So I see no clauses which would exclude [expr.ass]/2 from applying, that the value of the right-hand side is stored in the object referred to by the left.
最新草案围绕[basic.lval]/7和[expr]/9-10中的子句移动,但似乎并没有改变其含义,甚至重新措辞了[expr.ass]/2要更清楚:
The latest draft moves around the clauses that were in [basic.lval]/7 and [expr]/9-10 but doesn't seem to change their meaning, and it even re-words [expr.ass]/2 to be clearer:
在简单赋值(
=
)中,通过用右操作数的结果替换其值来修改左操作数所引用的对象.
In simple assignment (
=
), the object referred to by the left operand is modified by replacing its value with the result of the right operand.
推荐答案
据我所知,可修改的左值"的定义是在C ++中未指定,或者有意将数组指定为可分配的(我怀疑前者是正确的,因为没有编译器会后者).
As far as I can tell, the definition of "modifiable lvalue" is either under-specified in C++, or arrays have been intentionally been specified to be assignable (I suspect that former is true, since no compiler does latter).
标准(最新草案)说:
[basic.lval]
[basic.lval]
左值是可修改的,除非其类型为const限定或为函数类型.
An lvalue is modifiable unless its type is const-qualified or is a function type.
这很简洁,但是没有排除数组.
This is quite concise, but there is no exclusion of arrays.
此外,至少自C ++ 03起,这在标准版本中并未发生变化,该版本指定了以下内容:
Furthermore, this hasn't changed through standard versions at least since C++03, which specifies following:
[basic.lval]
[basic.lval]
11无法修改函数,但是可以修改指向函数的指针.
11 Functions cannot be modified, but pointers to functions can be modifiable.
12可以修改指向不完整类型的指针....
12 A pointer to an incomplete type can be modifiable. ...
13不得修改const限定表达式的引用对象...
13 The referent of a const-qualified expression shall not be modified ...
除了使用措辞多于定语外,其余大部分相同.不排除数组.
Which is mostly same, except using more descriptive than definitive wording. No exclusion of arrays.
相比之下,C11标准是透明的(引用N1548草案):
By contrast, C11 standard is crystal clear (quoting N1548 draft):
6.3.2.1左值,数组和函数指示符
6.3.2.1 Lvalues, arrays, and function designators
1 ...可修改的左值是没有数组类型的左值,...
1 ... A modifiable lvalue is an lvalue that does not have array type, ...
这篇关于在C ++ 17中分配给数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!