这是一些代码:
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 似乎也不适用: =
需要一个纯右值作为右操作数,并且提供了一个纯右值。 (它期望一个 glvalue 作为左操作数,并且提供了一个 glvalue)。如果在期望纯右值的地方提供了左值,则这些条款适用,反之亦然。
[expr.ass]/3 表示右表达式被隐式转换为左操作数的类型。但由于双方都有相同的类型 int[3]
,因此似乎没有必要进行转换。
所以我没有看到任何子句会排除 [expr.ass]/2 的应用,即右侧的值存储在左侧引用的对象中。
最新的草案围绕 [basic.lval]/7 和 [expr]/9-10 中的条款移动,但似乎并没有改变它们的含义,它甚至重新表述了 [expr.ass]/2 更清楚:
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++ 中未指定,要么数组已被有意指定为可赋值(我怀疑前者是正确的,因为没有编译器做后者)。
标准(最新草案)说:
[basic.lval]
An lvalue is modifiable unless its type is const-qualified or is a function type.
这很简洁,但不排除数组。
此外,至少自 C++03 以来,这在标准版本中没有改变,它指定了以下内容:
[basic.lval]
11 Functions cannot be modified, but pointers to functions can be modifiable.
12 A pointer to an incomplete type can be modifiable. ...
13 The referent of a const-qualified expression shall not be modified ...
除了使用比确定性措辞更具描述性的措辞外,这大部分是相同的。不排除数组。
相比之下,C11 标准非常清晰(引用 N1548 草案):
6.3.2.1 Lvalues, arrays, and function designators
1 ... A modifiable lvalue is an lvalue that does not have array type, ...
关于c++ - C++17 中的数组赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57439129/