Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分配给C+中的数组+;17_C++_Arrays_Language Lawyer_C++17_Variable Assignment - Fatal编程技术网

C++ 分配给C+中的数组+;17

C++ 分配给C+中的数组+;17,c++,arrays,language-lawyer,c++17,variable-assignment,C++,Arrays,Language Lawyer,C++17,Variable Assignment,下面是一些代码: int main() { using T = int[3]; T a; a = T{}; } 据我所知,根据C++17标准,这段代码是正确的,但是我尝试的每个编译器都拒绝了它 这个代码真的不正确吗?如果是,根据本标准的哪些条款 我的调查到目前为止:在C和旧版本的C++中,代码是不正确的,因为赋值操作符的左操作数必须是可修改的LValk,其中 A 不是,或者它不明确指定。但是由于C++17a被明确指定为可修改的左值(C++17[basic.lval]/

下面是一些代码:

int main()
{
    using T = int[3];
    T a;
    a = T{};
}
据我所知,根据C++17标准,这段代码是正确的,但是我尝试的每个编译器都拒绝了它

这个代码真的不正确吗?如果是,根据本标准的哪些条款


<>我的调查到目前为止:在C和旧版本的C++中,代码是不正确的,因为赋值操作符的左操作数必须是可修改的LValk,其中<代码> 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进行了修改,以使其更加清晰:

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


我可以说,“可修改的LValk”的定义要么是在C++中指定的,要么是有意指定数组是可分配的(我怀疑前者是真的,因为没有编译器后面的)。 标准(最新草案)规定:

[basic.lval]

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

这相当简洁,但不排除数组

此外,至少在C++03之后,这一点在标准版本中没有改变,C++03规定了以下内容:

[basic.lval]

11函数不能修改,但指向函数的指针可以修改

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

13常量限定表达式的引用项不得修改

除了使用更具描述性而非确定性的措辞外,它们基本上是相同的。不排除数组


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

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

1。。。可修改的左值是没有数组类型的左值


因为内置运算符也受[over.build]控制,即:

本款规定了代表[expr]条款中定义的内置运算符的候选运算符函数

对于赋值运算符,相应函数的形式为:

对于每一个三元组(L,vq,R),其中L是一个算术类型,R是一个提升的算术类型,存在以下形式的候选运算符函数

对于每一对(T,vq),其中T是任何类型,存在形式为的候选算子函数

Tvq&运算符=(T-vq&,T*)

对于每对(T,vq),其中T是成员类型的枚举或指针,存在以下形式的候选运算符函数

vqt&算子=(vqt&算子)


因此,当相应的参数是
a,T{}
时,它们都不能作为候选函数。因此,程序应该是不正确的。< /P> < P>没有一个在C++标准中对PR值数组的具体化的规定,如你在[Caldia.临时] / 5中看到的,它总结了这些实体化发生的情况。

”但是因为C++ 17代码> A < /C> >被明确地规定为可修改的LValk(C++ 17 [ Basic。LVAL]/7)。--您可以引用相关文本作为方便的参考吗?那么您想为您的变量指定一个未初始化的值吗?@iammilind@SidS
T{}
将所有数组元素初始化为
0
。有人可能会说,实际上从未禁止对数组进行赋值,如果是这样,那么。。。(头脑发热),据我所知,“可修改的LValk”的定义在C++中是指定的,或者,数组被有意指定为可分配的,我认为有人将可修改的LValk定义引入到C++标准中,将LoalsOffice与对象混淆。因为指示数组类型的对象必须是不可修改的对象。我已删除此注释,请检查较新的草稿。可修改左值的历史很有趣。AFAIK Richard Smith将左值与对象混淆,告诉他数组类型的对象可以修改,这就是为什么数组类型的左值不应该被排除在可修改的左值之外,并改变了可修改的左值定义。然后他在STD讨论中天真地写道,C++中没有任何东西禁止对数组的赋值。顺便说一下,他告诉我们,他是指数组在口语意义上是可修改的,在C++中,只有标量类型的对象可以被修改。相反,它的元素可以修改,也就是说,一个对象的子对象可以修改并不意味着这样一个完整的对象可以修改,它们是两个概念;第2.1、2.3和2.6点还规定了prvalue数组具体化的一些情况。案例
auto&&b=T{}将在第2.1点下,具体化prvalue数组。@M.M“注释不规范”请参见我的问题。参考文献