将 xvalue 转换为非常量左值引用时,为什么 gcc 和 clang 中的编译器错误不一致?

Sna*_*Pin 12 c++ gcc clang language-lawyer clang++

有人可以解释为什么两个编译器都在第二个示例中抛出错误而只有 gcc 在第一个示例中抛出错误吗?它是否与static_cast作为 xvalue的结果有关?

int& example1 = reinterpret_cast<int&>(static_cast<int&&>(10));
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) no errors

int& example2 = reinterpret_cast<int&>(10);
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) error: reinterpret_cast from rvalue to reference type 'int &'
Run Code Online (Sandbox Code Playgroud)

我也不确定,但我认为第一个例子是格式良好的,因为根据标准,xvalue 是 glvalue 的一种类型,对吧?并且标准的这个[expr.reinterpret.cast]/11部分说我应该能够将 T1 泛左值转换为“对 T2 的引用”类型,在这种情况下,T1 与 T2 的类型相同。

dfr*_*fri 3

\n
reinterpret_cast<int&>(10);\n
Run Code Online (Sandbox Code Playgroud)\n
\n

该程序格式错误,因为转换而来的表达式是纯右值。来自[expr.reinterpret.cast]/1

\n
\n

表达式的结果是将表达式转换为 typereinterpret_\xc2\xadcast<T>(v)的结果。如果是左值引用类型或函数类型的右值引用,则结果是左值;[...]下面列出了可以使用显式执行的转换。不能使用显式执行其他转换vTTreinterpret_\xc2\xadcastreinterpret_\xc2\xadcast

\n
\n

以下条款均不允许reinterpret_cast来自非指针的 (p)rvalue。

\n
\n
#include <memory>\nreinterpret_cast<int&>(std::move(10));\n
Run Code Online (Sandbox Code Playgroud)\n

这里,要转换的表达式是 xvalue,如@LanguageLawyer 评论中链接的问答中所示链接的问答中所示(这可以说是此问答的欺骗目标)

\n\n

从 C++14 开始(也作为 DR 修复更新到 C++11)以及CWG 1268的实际实现,这是格式良好的 ,这是格式良好的:

\n
\n

1268.xvalue操作数的reinterpret_cast节:8.2.10 [expr.reinterpret.cast]

\n

状态:CD3

\n

提交者:Michael Wong

\n

日期:2011-03-21

\n

[在 2012 年 10 月的会议上移至 DR。]

\n

8.2.10 [expr.reinterpret.cast] 第 11 段,处理转换为引用类型,仅允许左值操作数。当目标是右值引用类型时,大概应该允许使用左值操作数。

\n

[...]

\n
\n

请注意,强调的部分建议仅当目标是右值引用时才允许这样做,但实际更新的[expr.reinterpret.cast]/11删除了此限制。

\n

因此,GCC 拒绝第一个例子是错误的。

\n