Интересно, какие части стандарта указать, что в следующем сегменте коды:С ++: степень конверсия именующих ссылок и RValue ссылкой
#include <memory>
class A { };
class B : public A { };
int main()
{
std::unique_ptr<B> bptr = std::make_unique<B>(); // (a)
std::unique_ptr<A> aptr = std::move(bptr); // (b)
std::unique_ptr<A> &aptr_r = bptr; // (c)
std::unique_ptr<A> &&aptr_rr = std::move(bptr); // (d)
return 0;
}
(D) компилирует и (с) не делает. Пожалуйста, включите соответствующие части стандарта в свой ответ или обратитесь к ним соответствующим образом. Просто для справки, Ubuntu лязг версия 3.6.2-1 (теги/RELEASE_362/финал) (на основе LLVM 3.6.2) дает мне
error: non-const lvalue reference to type 'unique_ptr<A>' cannot
bind to a value of unrelated type 'unique_ptr<B>'
std::unique_ptr<A> &aptr_r = bptr;
^ ~~~~
и GCC (Ubuntu 5.2.1-22ubuntu2) 5,2 0,1 20151010 дает мне
error: invalid initialization of reference of type ‘std::unique_ptr<A>&’
from expression of type ‘std::unique_ptr<B>’
std::unique_ptr<A> &aptr_r = bptr;
^
Edit:
Чтобы сделать мой вопрос более ясным, позвольте мне добавить
class C { };
std::unique_ptr<C> cptr = std::make_unique<C>(); // (e)
std::unique_ptr<A> &&aptr_rr2 = std::move(cptr); // (f)
Что удерживает (f) от компиляции, когда (d) делает? Очевидно A
и C
не связаны между собой, но где, что обнаруживается, когда std::unique_ptr
конструктор используется для создания временного для обоих (d) и (е) является
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u);
(http://coliru.stacked-crooked.com/a/7e47cee922d95250) – chris
' (с) ' не компилируется, потому что 'aptr_r' и' bptr' имеют разные типы, и, таким образом, 'aptr_' не может стать ссылкой на' bptr'. Это так: 'int x = 0; float & y = x; '. Но '(d)' компилируется, потому что временный объект целевого типа создается из выражения 'std :: move (bptr)' .. и временный объект привязывается к ссылке rvalue. Обратите внимание, что как только вы создадите эту ссылку rvalue, 'bptr' станет нулевой, поскольку она была перемещена. – Nawaz