How does returning std::make_unique<SubClass> work?
std::unique_ptr
is not copyable, only movable. The reason you can return std::make_unique<Derived>
from a function declared to return std::unique_ptr<Base>
is that there is a conversion from one to the other.
So 1) is equivalent to:
std::unique_ptr<Base> GetDerived() {
return std::unique_ptr<Base>(std::made_unique<Derived>());
}
Since the value returned from std::make_unique
is an rvalue, the return value is move-constructed.
Contrast that to 2), which is equivalent to:
std::unique_ptr<Base> GetDerived2() {
std::unique_ptr<Derived> a = std::make_unique<Derived>();
return std::unique_ptr<Base>(a);
}
since a
is an lvalue, the return value must be copy-constructed, and std::unique_ptr
is non-copyable.
3) works because you cast the lvalue a
to an rvalue, and the return value can be move-constructed.
4) and 5) work because you already have a std::unique_ptr<Base>
and don't need to construct one to return.