_in my experience_ writing hi-performance multithreaded IO code with low level APIs - objects _never_ have tricky lifetime. RAII is extremely helpful whether you write async callback code (libuv) or lock-free multithreading.
RAII forces you to clearly define ownership. Shared_ptr is never a right choice.
“Explicit” is not a virtue, just noise. From experience, if you need something tricky with your object lifetime than it likely means your code needs fixing and you are likely to have other bugs.
Defer is trivially emulatable with a scope guard pattern - though I’d only recommend it when you are working with a legacy C API.