为什么不能使用static_cast将数组类型的纯右值转换为相同类型?

#include <iostream>
int main(){
    using type = int[2];
    static_cast<type>(type{1,2});  //#1
}

锵和GCC都抱怨这#1是形成不良的,并给予怪异的诊断。

Clang 报告

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

海湾合作委员会报告

invalid 'static_cast' from type 'type' {aka 'int [2]'} to type 'type' {aka 'int [2]'}   

但是,根据expr.static.cast#4

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

把一个类型转换成同一个类型不就叫恒等转换吗?
over.best.ics#general-8

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

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

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

这意味着,假设一个结果对象将由t纯右值初始化。

#2也被 Clang 和 GCC 拒绝了。但是,这种情况应该被dcl.init.general#15.9捕获

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

根据 basic.lval#1.2

纯右值是一个表达式,其求值初始化一个对象或计算一个运算符的操作数的值,如它出现的上下文所指定,或者是一个类型为 cv void 的表达式。

在这种情况下,不是类型的纯右type值不能初始化结果对象吗?

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

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

以上是为什么不能使用static_cast将数组类型的纯右值转换为相同类型?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>