我们可以将非类 prvalue 转换为 xvalue 吗?

Can we const-cast a non-class prvalue to xvalue?

提问人:eca2ed291a2f572f66f4a5fcf57511 提问时间:5/3/2019 最后编辑:eca2ed291a2f572f66f4a5fcf57511 更新时间:5/3/2019 访问量:207

问:

请考虑 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++-7clang-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 指原始实体T1T2T1T2const_castconst_cast

    将其与紧随其后的那个进行比较(7.6.1.10,第 4 段 [expr.const.cast]):

    对于两种对象类型和 ,如果指针可以是 使用 显式转换为类型 “pointer to”,然后还可以进行以下转换:T1T2T1T2const_cast

    • 可以使用强制转换将类型的值显式转换为类型的左值T1T2const_cast<T2&>;
    • 可以使用强制转换将类型的 glvalue 显式转换为类型的 xvalue; 和T1T2const_cast<T2&&>
    • 如果 T1 是类类型,则可以使用 cast 将 type 的 prvalue 显式转换为 type 的 xvalueT1T2const_cast<T2&&>

    如果操作数是 glvalue,则引用const_cast的结果是指原始对象,否则引用引用临时具体化转换的结果

    这种对比似乎暗示,从非类 prvaluexvalue 的强制转换不会遭受临时的物化转换,这在我看来很奇怪。

那么,上面的例子的目的是什么呢?

C++ 强制转换 临时 const-cast

评论

2赞 Language Lawyer 5/3/2019
wg21.link/cwg1965
0赞 Language Lawyer 5/3/2019
const_cast的结果是指原始实体这种措辞显然是有缺陷的,因为在 C++17 及更高版本中,prvalues 不表示实体。
0赞 eca2ed291a2f572f66f4a5fcf57511 5/3/2019
@LanguageLawyer 所以,上面的例子是有缺陷的。谢谢。
0赞 Brian Bi 5/3/2019
@LanguageLawyer 措辞没有缺陷。您引用的措辞在第 3 段中,不适用于参考案例,即第 4 段。第 4 段中的措辞清楚地表明,如果操作数是 glvalue,则结果仅指原始对象。
0赞 Language Lawyer 5/3/2019
第3段的第一句和第二句@Brian没有关系?

答: 暂无答案