C++ 基元引用之间的静态\u转换

C++ 基元引用之间的静态\u转换,c++,static-cast,C++,Static Cast,是否定义了使用static\u cast从const unsigned char&转换为const unsigned long& constexpr unsigned char arr[sizeof(unsigned long long)]{ 1 }; constexpr bool value = static_cast<const unsigned long long&>(arr[0]) == 1; constexpr无符号字符arr[sizeof(unsigned lo

是否定义了使用
static\u cast
const unsigned char&
转换为
const unsigned long&

constexpr unsigned char arr[sizeof(unsigned long long)]{ 1 };
constexpr bool value = static_cast<const unsigned long long&>(arr[0]) == 1;
constexpr无符号字符arr[sizeof(unsigned long long)]{1};
constexpr bool value=static_cast(arr[0])==1;
插入
int main(){}
,编译时在Coliru、Ideone和VS2015上不会出现错误或警告。这实际上是安全的,还是不安全但不需要给出错误

好处:我没想到
arr[0]
会是一个常量表达式,但使用
value
作为常量表达式不会出错。这是因为
arr
是一个数组吗?

*它是未定义的,因为您通过引用一种类型来使用另一种类型。 *您使用了强制转换,因此编译器应该信任您是否可以执行该强制转换。 *它通常会按照您期望的方式工作,但我怀疑它的价值在大多数体系结构上都是真实的

事实上,我认为这里发生的是,const&您要强制转换的对象被绑定到一个临时对象,或者如果它发生在运行时,它将被绑定到一个临时对象。是的,你应该从这个值中得到
1
char
1将被复制到一个
无符号long
中,常量&将绑定到该字符串。我想它不会绑定到你制作的数组。这将是完全安全的,您可以忽略上面的大部分内容

您可以通过尝试转换为左值来测试这个想法。不过,您不必将数据设置为
constexpr


我认为C++14中的[expr.static.cast]/4涵盖了这一点:

表达式
e
可以使用
static\u cast(e)
形式的
static\u cast(e)
显式转换为类型
T
t,code>格式良好。这样的影响 显式转换与执行声明和初始化,然后使用临时变量作为转换结果相同

这将您的代码定义为等同于:

constexpr unsigned char arr[sizeof(unsigned long long)]{ 1 };

const unsigned long long &t (arr[0]);

constexpr bool value = (t == 1);
第二行现在已经很熟悉了:在[dcl.init.ref]/5下,允许从不同(非引用相关)类型的值初始化常量引用:

如果
T1
是非类类型,则会创建一个临时类型cv1
T1
,并从初始值设定项表达式初始化副本。然后将引用绑定到临时对象


啊,我忘了我不能像以前那样向后别名。要澄清的是,使用
static\u cast
创建引用UB吗?我不相信,但使用该引用我相信是的。@JamesRoot-我想我对会发生什么是错误的。我想你绑定到了一个临时的。我刚刚测试了它,你是对的,它构造了一个临时的并绑定到它。