提问人:eca2ed291a2f572f66f4a5fcf57511 提问时间:5/3/2019 最后编辑:eca2ed291a2f572f66f4a5fcf57511 更新时间:5/3/2019 访问量:207
我们可以将非类 prvalue 转换为 xvalue 吗?
Can we const-cast a non-class prvalue to xvalue?
问:
请考虑 7.6.1.10 第 3 段 [expr.const.cast] (N4810) 中的以下示例:
typedef int *A[3]; // array of 3 pointer to int
typedef const int *const CA[3]; // array of 3 const pointer to const int
...
A &&r2 = const_cast<A&&>(CA{}); // OK
因此,标准说这是一个合法的代码,但是
没有一个或编译良好。
g++-7
clang-6
事实上,这与各州
const_cast
相关的评论:llvm
.... if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isRValue()) { if (!SrcType->isRecordType()) { // Cannot const_cast non-class prvalue to rvalue reference type. But if // this is C-style, static_cast can do this. msg = diag::err_bad_cxx_cast_rvalue; return TC_NotApplicable; } // Materialize the class prvalue so that the const_cast can bind a // reference to it. NeedToMaterializeTemporary = true; } ...
这基本上意味着我们不能将非类 prvalue 具体化(=cast) 为 xvalue。
此外,上述示例源自的同一段说:
对于两个相似的类型和 ,类型的 prvalue 可以是 使用 .结果 a 指原始实体。
T1
T2
T1
T2
const_cast
const_cast
将其与紧随其后的那个进行比较(7.6.1.10,第 4 段 [expr.const.cast]):
对于两种对象类型和 ,如果指针可以是 使用 显式转换为类型 “pointer to”,然后还可以进行以下转换:
T1
T2
T1
T2
const_cast
- 可以使用强制转换将类型的左值显式转换为类型的左值
T1
T2
const_cast<T2&>
; - 可以使用强制转换将类型的 glvalue 显式转换为类型的 xvalue;
和
T1
T2
const_cast<T2&&>
- 如果
T1
是类类型,则可以使用 cast 将 type 的 prvalue 显式转换为 type 的 xvalue。T1
T2
const_cast<T2&&>
如果操作数是 glvalue,则引用const_cast的结果是指原始对象,否则引用引用临时具体化转换的结果。
这种对比似乎暗示,从非类 prvalue 到 xvalue 的强制转换不会遭受临时的物化转换,这在我看来很奇怪。
- 可以使用强制转换将类型的左值显式转换为类型的左值
那么,上面的例子的目的是什么呢?
答: 暂无答案
评论
const_cast
的结果是指原始实体这种措辞显然是有缺陷的,因为在 C++17 及更高版本中,prvalues 不表示实体。