LockedValue implementation
You don't need both version of the copy constructor.

    LockedValue(const LockedValue&amp; _other) :
        m_Value(_other.load())
    {}

    LockedValue(LockedValue&amp; _other) :
        LockedValue(static_cast&lt;const LockedValue&amp;&gt;(_other))
    {}


If this is a mutating copy constructor. Then just have the second one. Otherwise have the first one. Since the mutating one simple calls the const version I see no reason for the second one as a non const object will still bind to the const version.

Move operations are usually noexcept. I suppose your are potentially throwing. I would need to look up all the funtions called. You should check and if your move operations are non throwing then you need to make an appropriate comment.

    LockedValue(LockedValue&amp;&amp; _other) :
        m_Value(_other._takeValue())
    {}


A standard move is simply a swap. I suppose you would need a safe swap. Which would be doubly hard as you run into race conditions. But there is always std::lock to help you with that (But its an extra step).

    LockedValue&amp; operator =(LockedValue&amp;&amp; _other)
    {
        if (this != &amp;_other)
            store(_other._takeValue());
        return *this;
    }


Thay's nice. I think I learned a new thing for the day.

    template &lt;class T_, typename = std::enable_if_t&lt;std::is_convertible_v&lt;T_, T&gt;&gt;&gt;
    LockedValue&amp; operator =(T_&amp;&amp; _value)
    {
        store(std::forward&lt;T_&gt;(_value));
        return *this;
    }


And a correct usage of the mutable keyword.

    mutable std::mutex m_Mutex;