对C样式数组的reinterpret_cast是非法的C++11

Is reinterpret_cast to C-style array illegal C++11?

本文关键字:cast 非法 C++11 reinterpret 样式 数组      更新时间:2023-10-16

为什么下面的代码不受欢迎?

double d[4] = {0,1,2,3};
reinterpret_cast<double[2]>(d);

GCC声明它为invalid cast from type 'double*' to type 'double [2]',clang声明reinterpret_cast from 'double *' to 'double [2]' is not allowed

现在,如果意图不明显,我希望这段代码返回一个包含{0,1}的double[2],就像reinterpret_cast<double*>(d)一样。(因此,我知道它可以与指针一起工作,所以这不是我所要求的)

您可能想要的是

double (&d2)[2] = reinterpret_cast<double(&)[2]>(d);

但不确定它是否是学究式的未定义行为(就像reinterpret_cast的大多数用法一样)。

两个编译器都是正确的。

reinterpret_cast不是锤子,它是一种强大的精密工具。reinterpret_cast的所有使用都必须涉及至少一个指针或引用类型作为源或目标,但单位积分转换的退化情况除外(即允许reinterpret_castint转换为int,但不执行任何操作)

您有一个大小为4的数组(而不是指针)。您不能将其强制转换为大小为2的数组,原因很简单,即大小不正确。一个类似的例子是,不能将一个类的实例强制转换为另一个类实例,因为这没有任何意义。要获得一个具有{0,1}的数组,您必须制作一个全新的数组。

以下是正确的方法:

     double d[4] = {0,1,2,3};                                                    
     double copy[2]{};                                                           
     std::copy_n(std::begin(d),2,std::begin(copy)); 

如果你不想创建数组的副本,习惯做法是对范围而不是数组进行操作,那么标准库中的每个算法都对迭代器而不是容器进行操作是有原因的。