在C ++ 17中分配给数组 [英] Assignment to array in C++17

查看:67
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆