2016-01-20 2 views
14
class A{ 
public: 
    virtual ~A() {}; 
}; 

class B : public A{ }; 

int main(){ 

    A&& p = B(); 

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

} 

Выдает ошибку (G ++ 5.2.0):dynamic_cast и эталонный Rvalue

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 перед преобразованием в ссылку rvalue, но если я удалю std::move, он компилируется отлично. От cppreference:

dynamic_cast <new_type> (expression)

Подобно других выражений литых, результат:

именующего если new_type является именующим ссылочным типом (выражение должно быть именующим)

xvalue если new_type является ссылочным типом rvalue (выражение может быть lvalue или rvalue)

Даже 5.2.7 N3337:

dynamic_cast<T>(v)

Если T является типом указателя, v должен быть prvalue указателя завершить тип класса, и результатом является prvalue типа Т Если T - ссылочный тип lvalue, v должен быть lvalue полного типа класса, а результат является lзначением типа, указанного T. Если T является ссылочным типом rvalue, v должно быть выражением, имеющим полный тип класса, и результатом является значение x для типа, указанного T.

Единственное требование, заключающееся в том, что я использую полный тип класса, который std::move(p), не так ли?

+1

У Clang нет проблем с кодом – Cubbi

+0

Подтверждено gcc 5.3. Однако работает без вызова 'std :: move'. ;) – erip

+0

... как вы отметили в своем вопросе.Я должен читать вопросы более подробно. – erip

ответ

6

Ваш код, конечно, хорошо:

Если T является ссылка Rvalue типа, v должен быть выражением, имеющим полного типа класса, и результатом является xvalue типа упомянутых до T.

Предположительно, dynamic_cast не был обновлен должным образом, когда были введены RValue ссылки, и до сих пор применяет Преждеосвященных-C++ 11 правило, rvalues ​​будут связаны только const Lvalue ссылки (обратите внимание, что это не даже работу при изменении целевого типа на B const&&, несмотря на то, что это подразумевается сообщением об ошибке!).

Рубрики: #69390.

2

Это похоже на работу вместо:

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

не могу сказать вам, почему ваш неверен.

Смежные вопросы