Writing extensions for a GC'd language is painful or you let your interop code live in a GC world, I'm pretty sure you more or less always end up with the latter unless you add a way for the hosted language to support some way to control the host language (like JS code "understanding" std::shared_ptr's but that probably adds other securiy risks in terms of low-level exposure).
It's an engineering tradeoff, if you're 100% C++ you don't need that.
GC is another runtime dependency (or a really complex intrusive addition to your code), so if you don't absolutely need it I would avoid it in C++. A lot of C++ programs can avoid it with careful design.
If you need a better GC anyway, in the real world modern GC algorithms are likely more performant for your use case than shared_ptr. Thus shared_ptr should be thought of as the C++ answer only because a "real" GC is hard to implement, but if you implement a real GC anywhere just use it to replace shared_ptr as well. (I lean to use unique_ptr even when GC is available, but I reserve the right to change my mind if someone presents evidence)