If I'm understanding the problem, anytime you mess with the vectors of RenderPassContainer, PipelineContainer or Material, you are going to have a bunch of invalid pointers correct? I.e. this is the standard problem of iterator invalidation after modification in most stl containers.
There are a number of ways around the issue but you need to clarify your intentions. The first and easiest, if you don't need the content to be contiguous in memory, is to remove ownership from the containers and use pointers instead. The extra indirection solves the problem for the most part at a minimal cost, given that this sort of thing is a couple hundred times a frame, it should have limited to no noticeable overhead.
A second solution which is a bit more complicated but maintains the linear memory layout would be not using pointers but instead use indexes into the arrays. Adding new items will work without problems, removing items just means walking through all the vectors looking for indices >= the removed item and erasing it or subtracting one. This means that you need to move the add/remove interface to a top level owner of all the vectors so it can iterate them, but that's generally a good idea to centralize the API anyway.
The third solution is even a little more complicated but has properties which I needed in my system. I extend the index idea by adding a version tag to each index. Since I'm promising myself I will never have more than 65k materials in the system at any given time, this handle is a simple 32 bit value, 16 bits of index and 16 bits of version. Now, when I go to get the material via the handle, I first check that the version stored in the handle and the version in the slot match, if not I return nullptr. If the callers gets a nullptr they look up the material by hash and assuming is still exists they fix their internal handle. The reason for this solution is that I only ever add/remove things dynamically in tools or debug builds and the whole check and re-fetch thing compiles out to nothing in release, but it is still fast enough that debug builds are not hobbled by a bunch of overhead.
Again though, this all circles back to what are the requirements for you. I'd personally start with the second solution as it is easy, fast and leaves the important properties of your layout in place. The third solution is not suggested unless you start doing a lot of hot reloading, which is why I wanted it.