Really? I've seen tons of C++ code that's written using smart
pointers with objects living on the heap which then get passed
around all over the place.
Yes there is lots of old C++ code that does this, largely
because unique_ptr wasn't implementable until C++11 added R value
refs and move semantics.
Sure, a lot of stuff in D should be structs on the stack, but
there are plenty of cases where you need stuff on the heap, in
which case, you either have to let the GC take care of it
(which means no deterministic destruction), have something
specific own it and destroy it when it's no longer needed, or
reference count it so that it gets destroyed immediately after
it's no longer needed.
on the heap == unique_ptr
on the heap + multiple owners = shared_ptr
If you work in a codebase that properly uses unique types, like
Rust does by default, you soon notice how rare multiple owners
actually is.