I want to have a pool of shared objects whose class name is Shader. I want a "client" to be able to request a Shader with certain parameters from the pool manager, and if there's one already in the pool the manager will return a pointer or reference to it, otherwise it creates a new Shader and adds it to the pool before returning its reference. Easy enough so far.
However, I also want the Shaders to be automatically deleted when all the clients have finished with them. Is this possible by implementing the pool as a container of std::weak_ptr and returning std::shared_ptr to the clients? Ie if I call weak_ptr::lock() multiple times on the same object are the shared_ptrs it returns linked to each other correctly, or does it return independent shared_ptrs leading to undefined behaviour? cpprefrence.com implies the latter, but they don't explictly point out the danger of that, and it seems to me that an opportunity was missed to make weak_ptr considerably more useful.
Calling weak_ptr::lock() multiple times is ok, the returned shared_ptr is configured properly, i.e. all shared_ptr-s having the common pointee are sharing the reference counter.
Note that lock() returns non-null pointer iff there is at least one shared_ptr pointing to the object. If there was none then the object would have been already destroyed. Hence lock() absolutely must implement sharing right otherwise it would break on every call.
Finally shared_ptr supports custom deleter functions, they may be useful to remove stale entries from the cache.