dynamic_cast 和 rvalue 引用

16
class A{
public:
    virtual ~A() {};
};

class B : public A{ };

int main(){

    A&& p = B();

    dynamic_cast<B&&>(std::move(p));

}

抛出错误(g++ 5.2.0):
error: conversion to non-const reference type 'std::remove_reference<A&>::type& {aka class A&}' from rvalue of type 'A' [-fpermissive]

它试图将 std::move(p) 转换为类型 A&,但我无法理解为什么需要这样做。在转换为右值引用之前,我认为需要将 p 强制转换为 rvalue,但如果我删除 std::move,它就可以编译通过。来自 cppreference 的内容如下:

dynamic_cast < new_type > ( expression )

与其他强制转换表达式类似,其结果为:

如果 new_type 是左值引用类型,则为左值(expression 必须是左值)

如果 new_type 是右值引用类型,则为 xvalue(expression 可以是左值或右值

即使是 N3337 的 5.2.7:

dynamic_cast<T>(v)

如果 T 是指针类型,则 v 必须是指向完整类类型的 prvalue 指针,结果是类型为 T 的 prvalue。如果 T 是左值引用类型,则 v 必须是完整类类型的左值,结果是 T 所引用类型的左值。如果 T 是右值引用类型,则 v 必须是具有完整类类型的表达式,结果是 T 所引用类型的 xvalue。

那里唯一的要求是我使用完整类类型,std::move(p) 就是完整类类型,不是吗?


2
Clang对你的代码没有问题。 - Cubbi
已确认在gcc 5.3上可以工作。尽管如此,没有std::move调用也可以工作。;) - erip
正如您在问题中所指出的那样,我应该更仔细地阅读问题。 - erip
2个回答

7

你的代码当然没问题:

如果T是一个右值引用类型,v必须是一个具有完整类类型的表达式,结果是指向T所引用类型的xvalue。

可以想象,在引入rvalue引用时,dynamic_cast可能没有得到很好的更新,仍然执行C++11之前的规则,即只有将右值绑定到const左值引用上(请注意,即使将目标类型更改为B const&&,它仍然无法工作,尽管错误消息暗示这样做是可以的!)。

已提交为#69390


3
这似乎可以代替原来的方案实现:
B&& b = std::move(dynamic_cast<B&>(p));

无法告诉你为什么你的不正确。

(该句涉及个人主观情况,无法提供更多解释)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接