When to use raw pointers
We have seen that smart pointer types such as unique_ptr<T> and shared_ptr<T> shine when there is a need to describe ownership of a type T resource through the type system. Does that mean that T* has become useless?
No, of course not. The trick is to use it in controlled situations. The first is that for a function, being passed a T* as an argument should mean the function is an observer, not an owner, of that T. If your code base used raw pointers in that sense, you will most probably not run into trouble.
Secondly, you can use a raw pointer inside a class that implements your preferred ownership semantics. It’s fine to implement a container that manipulates objects through raw pointers (for example, a tree-like structure meant for various traversal orders), as long as that container implements clear copy and move semantics. What you don’t want to do is expose pointers to the internal nodes of your container to external code...