Given the following code:
#include <iostream>
#include <memory>
struct A {};
struct B : public A {};
std::pair<bool, std::unique_ptr<B>> GetBoolAndB() {
return { true, std::make_unique<B>() };
}
std::unique_ptr<A> GetA1() {
auto[a, b] = GetBoolAndB();
return b;
}
std::unique_ptr<A> GetA2() {
auto [a, b] = GetBoolAndB();
return std::move(b);
}
GetA1
does not compile, with this error:
C2440: 'return': cannot convert from 'std::unique_ptr<B,std::default_delete<_Ty>>' to 'std::unique_ptr<A,std::default_delete<_Ty>>'
while GetA2
does compile without errors.
I don't understand why I need to call std::move
to make the function work.
Edit
Just to clarify, as pointed out in comments by DanielLangr, my doubt was about the fact that
std::unique_ptr<A> GetA3() {
std::unique_ptr<B> b2;
return b2;
}
compiles and transfer ownership without the need for std::move
.
Now I understand that in case of GetA1
and GetA2
, with structured bindings it happens that b
is part of some object, and so it must be moved to become an rvalue reference.