c++ - C++17 中的数组赋值

标签 c++ arrays language-lawyer c++17 variable-assignment

这是一些代码:

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/

相关文章:

javascript - 根据json数据属性动态生成多个div

c++ - (c++) 节点 header 的语法错误

C++ 设置具有 const 成员的成员对象

c++ - C++ 中的 3-d 动画

C++ 值初始化 vector 迭代器比较

c++ - 是否应该将运算符声明为非成员非模板 friend

c++ - "trailing parameter pack"到底是什么

c++ - win32 GetConsoleMode() 错误代码 6

java - 在 Java 中使用数组时出现一些错误

c - C语言中如何确定数组的大小?