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.