The question is one of ownership
You make no mention of who owns the objects going into the container. Since the
shared_ptr is an option, there is probably some form of shared ownership and dynamic storage allocation. A clear definition of who owns the objects and how they are observed (i.e. who can observe them) will frame much of the implementation.
In my specific case, the class containing the container actually wouldn't care if a reference somehow became invalid.
The container is playing an observer role.
However there might be a more generalised answer and a 'rule of thumb', when one should use one approach over the other.
Given the semantics of the the
reference_wrapper there is a reasonable expectation that the object being referred to is valid whilst the
reference_wrapper is valid. In your case this may not apply, but in general this is true and any maintenance done on the code at a later date may well assume this.
Rule of thumb
Allow the lifetime of the shared ownership objects to be managed with a
std::shared_ptr and use the "observer"
std::weak_ptr in the container.
If the lifetime of the objects is not shared and somehow tied to the lifetime of container itself (via automatic storage duration), then the
reference_wrapper is viable (in a similar way it could even be a raw pointer).