Ciekawe, których części standardu określa, że w kolejnym segmencie kodu:C++ konwersji lwartości odniesienia i rvalue odwołuje
#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) kompiluje i (c) nie ma. Proszę podać odpowiednie części standardu w swojej odpowiedzi lub odnieść się do nich odpowiednio. Tylko w celach informacyjnych, Ubuntu wersja dzyń 3.6.2-1 (tags/RELEASE_362/final) (oparty na LLVM 3.6.2) daje mi
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;
^ ~~~~
i gcc (5.2.1-22ubuntu2 Ubuntu) 5,2 0,1 20151010 daje mi
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:
aby moje pytanie bardziej jasne, dodam
class C { };
std::unique_ptr<C> cptr = std::make_unique<C>(); // (e)
std::unique_ptr<A> &&aptr_rr2 = std::move(cptr); // (f)
Co to jest utrzymywanie (f) z kompilacji, gdy (d) ma miejsce? Oczywiście A
i C
są niezależne, ale gdzie jest wykrywany, gdy konstruktor std::unique_ptr
wykorzystane do skonstruowania tymczasowy dla obu (d) i (f) jest
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u);
(http://coliru.stacked-crooked.com/a/7e47cee922d95250) – chris
' (c) ' nie kompiluje się, ponieważ 'aptr_r' i' bptr' są różnych typów, a zatem 'aptr_' nie może być odniesieniem do' bptr'. Jest tak: 'int x = 0; float i y = x; '. Ale '(d)' kompiluje, ponieważ tymczasowy obiekt typu docelowego, jest tworzony z wyrażenia 'std :: move (bptr)' .. i tymczasowy obiekt wiąże się z referencją rvalue. Zwróć uwagę, że po utworzeniu tego odwołania rvalue, 'bptr' staje się puste, ponieważ zostało przeniesione. – Nawaz