In controlled circumstances, you can pass a shared pointer through a permalink. Make sure that no one is deleting the object at the same time, although it should not be too difficult if you are careful about who you link to.
In general, you should pass a generic pointer as a direct copy. This gives it the intended semantics: each area containing a copy of the common index keeps the object alive by virtue of its "share" in the property.
The only reason why it is not always necessary to pass by value is that the common pointer is copied at a certain price by updating the number of references to atoms; however, this may not be a serious problem.
Additional retreat:
Since the main question has been answered, it may be instructive to consider several ways to use a never- shared index. Here is a little thought experiment. Define the generic pointer type SF = std::shared_ptr<Foo> . To consider links, rather than passing arguments to functions, let's look at the type RSF = std::reference_wrapper<T> . That is, if we have a common pointer SF p(std::make_shared<Foo>()); , then we can create a reference shell with semantics values โโthrough RSF w = std::ref(p); . So much to customize.
Now everyone knows that pointer containers are a minefield. Thus, std::vector<Foo*> will become a maintenance nightmare, and any number of errors will result from improper lifecycle management. Worse conceptually, it is never clear who owns the objects whose pointers are stored in the container. Pointers can be a combination of pointers to dynamic objects, automatic objects, and garbage. No one can say. Therefore, the standard solution is to use std::vector<SF> . This is the correct way to use a shared pointer. On the other hand, what you should never use is std::vector<RSF> - it is an uncontrollable monster that is actually very similar to the original vector of bare pointers! For example, it is unclear whether the object to which you are holding a link is alive. Taking a reference to a common index defeated the entire target.
For the second example, suppose we have a common pointer SF p , as before. Now we have an int foo(SF) function that we want to run at the same time. The regular std::thread(foo, p) works just fine, as the thread constructor creates a copy of its arguments. However, if we said std::thread(foo, std::ref(p)) , we would have all kinds of problems: a common pointer in the call area may expire and destroy the object, and you will remain with a broken link and an invalid pointer!
I hope these two admittedly pretty far-fetched examples shed some light when you really want your generic pointers to be passed in a copy. In a well-designed program, it should always be clear who is responsible for what resources, and if used correctly, a common index is an excellent tool for working.