Double checked locking with shared_ptr
Your implementation of Double Checked Locking is semantically correct; the acquire and release fences provide minimal necessary ordering.

I am wondering why you are using standalone fences, which is almost never necessary..
It is more common to use memory ordering directly on atomic operations:

auto sp = std::atomic_load_explicit(&amp;(it-&gt;second), std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);

...

std::atomic_thread_fence(std::memory_order_release);
std::atomic_store_explicit(&amp;(it-&gt;second), sp, std::memory_order_relaxed);


Can be replaced with:

auto sp = std::atomic_load_explicit(&amp;(it-&gt;second), std::memory_order_acquire);

...

std::atomic_store_explicit(&amp;(it-&gt;second), sp, std::memory_order_release);


Furthermore, I understand why you are using (void) lock;, but I would not use that line just to suppress a compiler warning.
Also I am surprised about that warning since a modern compiler should know that RAII objects have a function. Are you sure there is a warning or is that an assumption ?