C++ 为什么可以';是否使用静态转换将数组类型的PRU值转换为相同类型? #包括 int main(){ 使用type=int[2]; 静态强制转换(类型{1,2});/#1 }

C++ 为什么可以';是否使用静态转换将数组类型的PRU值转换为相同类型? #包括 int main(){ 使用type=int[2]; 静态强制转换(类型{1,2});/#1 },c++,language-lawyer,c++20,C++,Language Lawyer,C++20,Clang和GCC都认为#1是病态的,并且给出了奇怪的诊断 叮当声报道 static_cast from 'int *' to 'type' (aka 'int [2]') is not allowed GCC报告 invalid 'static_cast' from type 'type' {aka 'int [2]'} to type 'type' {aka 'int [2]'} 然而,根据 如果存在从E到T的隐式转换序列([over.best.ics]),则表达式E可以显式转

Clang和GCC都认为
#1
是病态的,并且给出了奇怪的诊断

叮当声报道

static_cast from 'int *' to 'type' (aka 'int [2]') is not allowed  
GCC报告

invalid 'static_cast' from type 'type' {aka 'int [2]'} to type 'type' {aka 'int [2]'}   
然而,根据

如果存在从E到T的隐式转换序列([over.best.ics]),则表达式E可以显式转换为类型T

将一个类型转换为相同类型的操作不称为标识转换吗?

如果将参数与参数类型匹配不需要任何转换,则隐式转换序列是由标识转换([over.ics.scs])组成的标准转换序列

我认为这里的一个关键规则是

转换序列是[conv]中定义的隐式转换,这意味着它受单个表达式([dcl.init],[dcl.init.ref])初始化对象或引用的规则控制

这意味着,假设一个结果对象将是
t
,它将由prvalue初始化

type t=type{1,2};//#2.
#2
也被Clang和GCC拒绝。然而,这样的案件应该被警方抓获

否则,要初始化的对象的初始值就是初始值设定项表达式的(可能已转换)值。如有必要,将使用标准转换序列([conv])将初始值设定项表达式转换为目标类型的cv非限定版本;不考虑用户定义的转换。如果转换无法完成,则初始化格式错误。使用无法表示的值初始化位字段时,位字段的结果值由实现定义

prvalue是一个表达式,其求值初始化对象或计算运算符的操作数的值(由其出现的上下文指定),或者是一个类型为cv void的表达式

在这种情况下,类型为
type
的prvalue不是不能初始化结果对象吗

Clang假定数组到指针的转换应用于操作数。但是,只有当项目符号进入时,才允许进行这种转换。换句话说,此处的转换不应适用于项目符号4中的操作数


GCC给出了更不合理的诊断。我想知道为什么Clang和GCC禁止显式转换?

原始数组很难保持数组形式-在prvalue上下文中,数组指向指针

但它是否也适用于
静态\u cast
上下文?这些规则在……中概述

我们没有引用引用,因此我们跳过前3条,得出:

如果存在从
E
T
的隐式转换序列(),则表达式
E
可以显式转换为类型
T

这不起作用,因为():

表达式
E
可以隐式转换为类型
T
当且仅当声明
T=E
格式良好,对于某些发明的临时变量
t

intt[2]=int[2]{1,2}格式不正确。初始化数组的唯一合法方法在中指定:

。。。如果目标类型是数组,则对象初始化如下。设x1,…,xk为表达式列表的元素。。。第1个数组元素是用席初始化初始化的,每一个都是≤ 我≤ k

这里没有将int[2]{1,2}
展开到表达式列表中的规定

否则,结果对象将从
E
直接初始化

类似地,这与
intx[2](int[2]{1,2})不起作用的原因相同格式不正确

请注意,中有一项关于阵列的特殊规定,允许轻松复制(例如,
std::array
)。在原始阵列中没有这样的处理

我们跳过。6、7不适用。这让我们想到:

将左值到右值([conv.lval])、数组到指针([conv.array])和函数到指针([conv.func])的转换应用于操作数。
. . .

就这样,演员阵容无效。Clang和GCC似乎都是正确的。错误报告略有不同,因为Clang报告的是衰减类型,而GCC报告的是原始类型


作为一种解决方法,转换为引用类型:
static_-cast(类型{1,2})

这似乎与prvalues没有直接关系:
类型v{1,2};静态铸型(v);v[0]=v[1]
也会导致相同的强制转换问题(尽管这里的
v
应该是glvalue)。@JérômeRichard没有可以将glvalue
v
转换为数组类型的prvalue的左值到右值转换。。如果将参数与参数类型匹配不需要任何转换,则问题在于没有数组类型的函数参数。@LanguageLawyer,这将使许多事情变得不合理。考虑,假设数组是多维数组类型。如果参数类型为“nx数组”。。。。如果存在从初始值设定项列表的每个元素到X的隐式转换序列,则该序列将是错误的。因为数组的元素也是数组类型。没有那种数组类型的函数参数。我认为apply to[over.ics.list]/6在这方面也没有太大变化,但ok,链接更新了。主要问题是,在prvalue上下文中,数组会衰减为指针。你说的相关规则是什么?@xmh0511.你认为
type{1,2}
是一个glvalue吗?int t[2]=int[2]{1,2};对于这个案子,我和Jens Maurer的观点是一样的,我们认为应该是有条理的。对于从E直接初始化的
,您说它的形式是
intx[2](int[2]{1,2}),这里很模糊。它可以说是